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/06/26 13:25:26 UTC

[isis] branch master updated: ISIS-1720: MM fundamentals: remove ObjectFeature#getName and #getDescription

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

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


The following commit(s) were added to refs/heads/master by this push:
     new df3c071  ISIS-1720: MM fundamentals: remove ObjectFeature#getName and #getDescription
df3c071 is described below

commit df3c07106d29e8803c233a0145d6bc1424d7a061
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jun 26 15:25:11 2021 +0200

    ISIS-1720: MM fundamentals: remove ObjectFeature#getName and
    #getDescription
    
    as we now have imperative replacements
---
 .../isis/applib/services/iactn/PropertyEdit.java   |  3 +-
 .../core/metamodel/facets/DomainEventHelper.java   |  5 +-
 .../actions/action/invocation/CommandUtil.java     |  8 ++-
 .../DomainServiceFacetAnnotationFactory.java       | 10 ++--
 .../impl/ObjectValidPropertiesFacetImpl.java       | 15 +++---
 .../metamodel/interactions/InteractionHead.java    |  6 +--
 .../interactions/managed/ManagedMember.java        |  6 +--
 .../managed/ParameterNegotiationModel.java         | 28 +++++-----
 .../bootstrap3/GridSystemServiceBootstrap.java     |  8 +--
 .../isis/core/metamodel/spec/ManagedObject.java    |  7 +++
 .../core/metamodel/spec/ObjectSpecification.java   |  9 ++--
 .../core/metamodel/spec/feature/ObjectAction.java  | 38 ++++++-------
 .../spec/feature/ObjectActionParameter.java        |  6 ++-
 .../metamodel/spec/feature/ObjectAssociation.java  |  6 ++-
 .../core/metamodel/spec/feature/ObjectFeature.java | 46 +++++++++-------
 .../spec/feature/OneToOneAssociation.java          | 20 ++++---
 .../specloader/specimpl/FacetedMethodsBuilder.java | 27 +++++-----
 .../specloader/specimpl/ObjectActionDefault.java   |  6 ++-
 .../specimpl/ObjectActionParameterAbstract.java    | 62 ++++++++++++++++------
 .../specloader/specimpl/ObjectMemberAbstract.java  | 45 +++++++++++-----
 .../specimpl/OneToManyAssociationDefault.java      |  7 +--
 .../specimpl/OneToOneAssociationDefault.java       | 34 ++++++------
 .../core/metamodel/util/snapshot/XmlSnapshot.java  | 18 +++----
 .../objects/ObjectActionLayoutXmlDefaultTest.java  |  2 +-
 .../objects/OneToManyAssociationDefaultTest.java   |  2 +-
 ...ionParameterAbstractTest_getId_and_getName.java | 40 +++++++-------
 .../command/CommandDtoFactoryDefault.java          | 24 +++++----
 .../executor/MemberExecutorServiceDefault.java     | 15 ++----
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    |  2 +-
 .../AbstractCollectionInvocationHandler.java       |  7 ---
 .../handlers/CollectionInvocationHandler.java      |  3 +-
 .../handlers/DomainObjectInvocationHandler.java    | 36 ++++++-------
 .../wrapper/handlers/MapInvocationHandler.java     | 11 ++--
 .../wrapper/handlers/ProxyContextHandler.java      | 20 ++++---
 .../ui/components/ExcelFileModel.java              | 26 ++++-----
 .../ui/components/collections/TableViewFx.java     |  8 +--
 .../ui/components/collection/TableViewVaa.java     |  8 +--
 .../DomainModelTest_usingGoodDomain.java           | 54 +++++++++----------
 .../excel/applib/dom/util/ExcelConverter.java      | 23 ++++----
 .../common/model/action/ActionUiMetaModel.java     | 18 +------
 .../common/model/action/form/FormUiModel.java      | 14 ++++-
 .../viewer/common/model/feature/ScalarUiModel.java |  6 +--
 .../restfulobjects/rendering/IResourceContext.java |  3 +-
 .../restfulobjects/rendering/RendererFactory.java  |  2 +-
 .../restfulobjects/rendering/ReprRenderer.java     |  6 +--
 .../rendering/ReprRendererAbstract.java            | 28 +++++-----
 .../viewer/restfulobjects/rendering/Responses.java | 14 ++---
 .../AbstractObjectMemberReprRenderer.java          | 36 ++++++-------
 .../domainobjects/ActionResultReprRenderer.java    |  7 +--
 .../domainobjects/DomainObjectReprRenderer.java    |  3 +-
 .../rendering/domainobjects/ListReprRenderer.java  |  5 +-
 .../rendering/domainobjects/MemberType.java        |  3 +-
 .../domainobjects/ObjectActionReprRenderer.java    | 11 ++--
 .../ObjectCollectionReprRenderer.java              |  5 +-
 .../domainobjects/ObjectPropertyReprRenderer.java  |  2 +-
 .../domainobjects/ScalarValueReprRenderer.java     |  3 +-
 .../AbstractTypeFeatureReprRenderer.java           | 28 ++++++----
 .../AbstractTypeMemberReprRenderer.java            | 14 +++--
 .../domaintypes/ActionDescriptionReprRenderer.java | 61 +++++++++++++--------
 .../ActionParameterDescriptionReprRenderer.java    | 30 ++++++++---
 .../CollectionDescriptionReprRenderer.java         | 38 ++++++++-----
 .../domaintypes/DomainTypeReprRenderer.java        |  5 +-
 .../PropertyDescriptionReprRenderer.java           | 38 +++++++++----
 .../domaintypes/TypeActionResultReprRenderer.java  | 10 ++--
 .../domaintypes/TypeListReprRenderer.java          |  2 +-
 ...entNegotiationServiceForRestfulObjectsV1_0.java | 19 ++++---
 .../ContentNegotiationServiceOrgApacheIsisV2.java  |  6 +--
 .../service/swagger/internal/Generation.java       | 26 ++++++---
 .../viewer/resources/HomePageReprRenderer.java     |  7 +--
 .../resources/ObjectAdapterUpdateHelper.java       |  8 +--
 .../viewer/resources/UserReprRenderer.java         |  3 +-
 .../viewer/resources/VersionReprRenderer.java      |  3 +-
 .../viewer/wicket/model/models/ActionModel.java    | 22 ++++----
 .../wicket/model/models/ScalarParameterModel.java  |  6 +--
 .../wicket/model/models/ScalarPropertyModel.java   | 14 ++---
 .../ui/components/actioninfo/ActionInfoPanel.java  |  2 +-
 .../actionprompt/ActionPromptHeaderPanel.java      |  4 +-
 .../components/actions/ActionParametersPanel.java  |  4 +-
 .../CollectionContentsAsAjaxTablePanel.java        |  7 +--
 .../summary/CollectionContentsAsSummary.java       | 17 +++---
 .../entity/collection/EntityCollectionPanel.java   | 12 +++--
 .../components/layout/bs3/tabs/TabGroupPanel.java  |  6 +--
 .../ui/components/property/PropertyEditPanel.java  |  3 +-
 .../PropertyEditPromptHeaderPanel.java             |  2 +-
 .../scalars/ScalarPanelSelectAbstract.java         |  4 +-
 .../scalars/ScalarPanelTextFieldAbstract.java      |  2 +-
 .../blobclob/IsisBlobOrClobPanelAbstract.java      | 20 +++----
 .../scalars/image/JavaAwtImagePanel.java           |  2 +-
 .../scalars/markup/ParentedMarkupPanel.java        | 10 ++--
 .../components/scalars/primitive/BooleanPanel.java |  2 +-
 .../scalars/reference/ReferencePanel.java          |  6 +--
 .../StandaloneCollectionPanel.java                 |  2 +-
 .../wicket/ui/components/tree/TreePanel.java       |  4 +-
 .../linkandlabel/LinkAndLabelFactoryAbstract.java  |  3 +-
 .../StandaloneCollectionPage.java                  |  2 +-
 .../viewer/wicket/ui/pages/value/ValuePage.java    |  4 +-
 .../wicket/ui/pages/voidreturn/VoidReturnPage.java |  2 +-
 97 files changed, 744 insertions(+), 583 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java
index 10d2edf..d4eccb3 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java
@@ -28,7 +28,8 @@ import lombok.Getter;
 /**
  * @since 1.x {@index}
  */
-public class PropertyEdit extends Execution<PropertyEditDto, PropertyDomainEvent<?, ?>> {
+public class PropertyEdit
+extends Execution<PropertyEditDto, PropertyDomainEvent<?, ?>> {
 
     @Getter
     private final Object newValue;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
index ab30e9d..5dc1b30 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
@@ -135,7 +135,8 @@ public class DomainEventHelper {
                     val parameters = objectAction.getParameters();
 
                     val parameterNames = parameters.stream()
-                            .map(ObjectActionParameter::getName)
+                            .map(ObjectActionParameter::getStaticFriendlyName)
+                            .map(optional->optional.orElseThrow(_Exceptions::unexpectedCodeReach))
                             .collect(_Lists.toUnmodifiable());
 
                     final List<Class<?>> parameterTypes = parameters.stream()
@@ -257,7 +258,7 @@ public class DomainEventHelper {
         }
     }
 
-    private static <S,T> void setEventNewValue(PropertyDomainEvent<S, T> event, T newValue) {
+    private static <S,T> void setEventNewValue(final PropertyDomainEvent<S, T> event, final T newValue) {
         event.setNewValue(newValue);
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java
index 98c154d..cc02850 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java
@@ -24,6 +24,7 @@ import java.util.List;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Arrays;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.commons.StringExtensions;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -44,10 +45,6 @@ public class CommandUtil {
 
     private CommandUtil(){}
 
-    public static String targetMemberNameFor(final ObjectMember objectMember) {
-        return objectMember.getName();
-    }
-
     public static String targetClassNameFor(final ManagedObject targetAdapter) {
         return targetClassNameFor(targetAdapter.getSpecification());
     }
@@ -121,7 +118,8 @@ public class CommandUtil {
             final ObjectActionParameter param,
             final ManagedObject objectAdapter) {
 
-        final String name = param.getName();
+        final String name = param.getStaticFriendlyName()
+                .orElseThrow(_Exceptions::unexpectedCodeReach);
         appendArg(buf, name, objectAdapter);
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java
index 4971fe8..2043d12 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java
@@ -68,9 +68,9 @@ implements MetaModelRefiner {
 
             final String associationNames = spec
                     .streamAssociations(MixedIn.EXCLUDED)
-                    .map(ObjectAssociation::getName)
-                    // it's okay to have an "association" called "Id" (corresponding to getId() method)
-                    .filter(associationName->!"Id".equalsIgnoreCase(associationName))
+                    .map(ObjectAssociation::getId)
+//                    // it's okay to have an "association" called "Id" (corresponding to getId() method)
+//                    .filter(associationName->!"Id".equalsIgnoreCase(associationName))
                     .collect(Collectors.joining(", "));
 
             if(associationNames.isEmpty()) {
@@ -79,7 +79,9 @@ implements MetaModelRefiner {
 
             ValidationFailure.raiseFormatted(
                     spec,
-                    "%s: services can only have actions ('%s' config property), not properties or collections; annotate with @Programmatic if required.  Found: %s",
+                    "%s: services can only have actions ('%s' config property), "
+                    + "not properties or collections; "
+                    + "annotate with @Programmatic if required. Found: %s",
                     spec.getFullIdentifier(),
                     "'isis.core.meta-model.validator.serviceActionsOnly'",
                     associationNames);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
index feb8f49..29a10d6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
@@ -25,10 +25,9 @@ import org.apache.isis.core.metamodel.facets.object.objectvalidprops.ObjectValid
 import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 
-public class ObjectValidPropertiesFacetImpl extends ObjectValidPropertiesFacetAbstract {
+public class ObjectValidPropertiesFacetImpl
+extends ObjectValidPropertiesFacetAbstract {
 
     // REVIEW: should provide this rendering context, rather than hardcoding.
     // the net effect currently is that class members annotated with
@@ -47,18 +46,16 @@ public class ObjectValidPropertiesFacetImpl extends ObjectValidPropertiesFacetAb
         final StringBuilder buf = new StringBuilder();
         final ManagedObject adapter = context.getTarget();
 
-        adapter.getSpecification().streamAssociations(MixedIn.EXCLUDED)
-        .filter(ObjectAssociation.Predicates.PROPERTIES)
+        adapter.getSpecification().streamProperties(MixedIn.EXCLUDED)
         .filter(property->property.isVisible(adapter, context.getInitiatedBy(), where).isVetoed()) // ignore hidden properties
         .filter(property->property.isUsable(adapter, context.getInitiatedBy(), where).isVetoed())  // ignore disabled properties
         .forEach(property->{
-            final OneToOneAssociation otoa = (OneToOneAssociation) property;
-            final ManagedObject value = otoa.get(adapter, context.getInitiatedBy());
-            if (otoa.isAssociationValid(adapter, value, context.getInitiatedBy()).isVetoed()) {
+            final ManagedObject value = property.get(adapter, context.getInitiatedBy());
+            if (property.isAssociationValid(adapter, value, context.getInitiatedBy()).isVetoed()) {
                 if (buf.length() > 0) {
                     buf.append(", ");
                 }
-                buf.append(property.getName());
+                buf.append(property.getFriendlyName(context::getTarget));
             }
         });
         if (buf.length() > 0) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java
index 381ee20..674dcc0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionHead.java
@@ -52,12 +52,12 @@ public class InteractionHead {
     @NonNull private final ManagedObject target;
 
     /** Regular case, when owner equals target. (no mixin) */
-    public static InteractionHead regular(ManagedObject owner) {
+    public static InteractionHead regular(final ManagedObject owner) {
         return InteractionHead.of(owner, owner);
     }
 
     /** Mixin case, when target is a mixin for the owner. */
-    public static InteractionHead mixin(@NonNull ManagedObject owner, @NonNull ManagedObject target) {
+    public static InteractionHead mixin(@NonNull final ManagedObject owner, @NonNull final ManagedObject target) {
         return InteractionHead.of(owner, target);
     }
 
@@ -74,7 +74,7 @@ public class InteractionHead {
     // -- HELPER
 
     /** factory with consistency checks */
-    private static InteractionHead of(@NonNull ManagedObject owner, @NonNull ManagedObject target) {
+    private static InteractionHead of(@NonNull final ManagedObject owner, @NonNull final ManagedObject target) {
         if(ManagedObjects.isSpecified(owner)
                 && owner.getSpecification().getBeanSort().isMixin()) {
             throw _Exceptions.unrecoverableFormatted("unexpected: owner is a mixin %s", owner);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java
index ff64289..99a78dc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java
@@ -104,7 +104,7 @@ public abstract class ManagedMember implements ManagedFeature {
      *
      * @param managedObject
      */
-    protected void setOwner(@NonNull ManagedObject managedObject) {
+    protected void setOwner(@NonNull final ManagedObject managedObject) {
         this.owner = managedObject;
     }
 
@@ -124,7 +124,7 @@ public abstract class ManagedMember implements ManagedFeature {
     }
 
     public String getName() {
-        return getMetaModel().getName();
+        return getMetaModel().getFriendlyName(null);
     }
 
     @Override
@@ -134,7 +134,7 @@ public abstract class ManagedMember implements ManagedFeature {
 
     @Override
     public String getDisplayLabel() {
-        return getMetaModel().getName();
+        return getMetaModel().getFriendlyName(this::getOwner);
     }
 
     @Getter @Setter @NonNull
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 0611fd9..ce94646 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
@@ -30,6 +30,7 @@ import org.apache.isis.commons.internal.binding._BindableAbstract;
 import org.apache.isis.commons.internal.binding._Bindables;
 import org.apache.isis.commons.internal.binding._Observables;
 import org.apache.isis.commons.internal.binding._Observables.LazyObservable;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.consent.InteractionResult;
@@ -113,7 +114,7 @@ public class ParameterNegotiationModel {
         return validationFeedbackActive;
     }
 
-    public void setParamValues(@NonNull Can<ManagedObject> paramValues) {
+    public void setParamValues(@NonNull final Can<ManagedObject> paramValues) {
         // allow overflow and underflow
         val valueIterator = paramValues.iterator();
         paramModels.forEach(paramModel->{
@@ -128,23 +129,23 @@ public class ParameterNegotiationModel {
         return paramModels;
     }
 
-    @NonNull public ObjectActionParameter getParamMetamodel(int paramNr) {
+    @NonNull public ObjectActionParameter getParamMetamodel(final int paramNr) {
         return paramModels.getElseFail(paramNr).getMetaModel();
     }
 
-    @NonNull public Bindable<ManagedObject> getBindableParamValue(int paramNr) {
+    @NonNull public Bindable<ManagedObject> getBindableParamValue(final int paramNr) {
         return paramModels.getElseFail(paramNr).getBindableParamValue();
     }
 
-    @NonNull public Observable<Can<ManagedObject>> getObservableParamChoices(int paramNr) {
+    @NonNull public Observable<Can<ManagedObject>> getObservableParamChoices(final int paramNr) {
         return paramModels.getElseFail(paramNr).getObservableParamChoices();
     }
 
-    @NonNull public Observable<String> getObservableParamValidation(int paramNr) {
+    @NonNull public Observable<String> getObservableParamValidation(final int paramNr) {
         return paramModels.getElseFail(paramNr).getObservableParamValidation();
     }
 
-    @NonNull public Bindable<String> getBindableParamSearchArgument(int paramNr) {
+    @NonNull public Bindable<String> getBindableParamSearchArgument(final int paramNr) {
         return paramModels.getElseFail(paramNr).getBindableParamSearchArgument();
     }
 
@@ -171,15 +172,15 @@ public class ParameterNegotiationModel {
     }
 
 
-    @NonNull public ManagedObject getParamValue(int paramNr) {
+    @NonNull public ManagedObject getParamValue(final int paramNr) {
         return paramModels.getElseFail(paramNr).getValue().getValue();
     }
 
-    public void setParamValue(int paramNr, @NonNull ManagedObject newParamValue) {
+    public void setParamValue(final int paramNr, @NonNull final ManagedObject newParamValue) {
         paramModels.getElseFail(paramNr).getBindableParamValue().setValue(newParamValue);
     }
 
-    @NonNull public ManagedObject adaptParamValuePojo(int paramNr, @Nullable Object newParamValuePojo) {
+    @NonNull public ManagedObject adaptParamValuePojo(final int paramNr, @Nullable final Object newParamValuePojo) {
         val paramMeta = getParamMetamodel(paramNr);
         val paramSpec = paramMeta.getSpecification();
         val paramValue = newParamValuePojo!=null
@@ -221,9 +222,9 @@ public class ParameterNegotiationModel {
         @Getter @NonNull private final LazyObservable<Can<ManagedObject>> observableParamChoices;
 
         private ParameterModel(
-                int paramNr,
-                @NonNull ParameterNegotiationModel negotiationModel,
-                @NonNull ManagedObject initialValue) {
+                final int paramNr,
+                @NonNull final ParameterNegotiationModel negotiationModel,
+                @NonNull final ManagedObject initialValue) {
 
             this.paramNr = paramNr;
             this.metaModel = negotiationModel.getHead().getMetaModel().getParameters().getElseFail(paramNr);
@@ -282,7 +283,8 @@ public class ParameterNegotiationModel {
 
         @Override
         public String getDisplayLabel() {
-            return getMetaModel().getName();
+            return getMetaModel().getStaticFriendlyName()
+                    .orElseThrow(_Exceptions::unexpectedCodeReach);
         }
 
         @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBootstrap.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBootstrap.java
index db2b9fa..0640888 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBootstrap.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBootstrap.java
@@ -112,7 +112,7 @@ public class GridSystemServiceBootstrap extends GridSystemServiceAbstract<BS3Gri
     // only ever called if fail to load DefaultGrid.layout.xml,
     // which *really* shouldn't happen
     //
-    private BS3Grid fallback(Class<?> domainClass) {
+    private BS3Grid fallback(final Class<?> domainClass) {
         final BS3Grid bs3Grid = withDomainClass(new BS3Grid(), domainClass);
 
         final BS3Row headerRow = new BS3Row();
@@ -137,7 +137,7 @@ public class GridSystemServiceBootstrap extends GridSystemServiceAbstract<BS3Gri
         return bs3Grid;
     }
 
-    private static BS3Grid withDomainClass(BS3Grid bs3Grid, Class<?> domainClass) {
+    private static BS3Grid withDomainClass(final BS3Grid bs3Grid, final Class<?> domainClass) {
         bs3Grid.setDomainClass(domainClass);
         return bs3Grid;
     }
@@ -479,7 +479,9 @@ public class GridSystemServiceBootstrap extends GridSystemServiceAbstract<BS3Gri
 
         for (final String collectionId : collectionIds) {
             final BS3Tab bs3Tab = new BS3Tab();
-            bs3Tab.setName(objectSpec.getAssociationElseFail(collectionId).getName());
+
+            // TODO[ISIS-1720] we have no imperative friendly name support here, what to do?
+            bs3Tab.setName(objectSpec.getCollectionElseFail(collectionId).getFeatureIdentifier().getMemberNaturalName());
             tabGroup.getTabs().add(bs3Tab);
             bs3Tab.setOwner(tabGroup);
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
index b17ef86..2ee3788 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
@@ -22,6 +22,7 @@ package org.apache.isis.core.metamodel.spec;
 import java.util.Optional;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.function.Supplier;
 
 import javax.annotation.Nullable;
 
@@ -69,6 +70,10 @@ public interface ManagedObject {
 
     boolean isBookmarkMemoized();
 
+    default Supplier<ManagedObject> asProvider() {
+        return ()->this;
+    }
+
     // -- TITLE
 
     public default String titleString() {
@@ -291,4 +296,6 @@ public interface ManagedObject {
     }
 
 
+
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index ada2b27..8db7b2d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -132,14 +132,15 @@ extends
     }
 
     /**
-     * @param onType
      * @since 2.0
      */
-    public default Optional<MixedInMember> getMixedInMember(final ObjectSpecification onType) {
-        return streamAnyActions(MixedIn.INCLUDED)
+    public default Optional<MixedInMember> lookupMixedInMember(final ObjectSpecification mixinSpec) {
+        return Stream.concat(
+                streamAnyActions(MixedIn.INCLUDED),
+                streamAssociations(MixedIn.INCLUDED))
                 .filter(MixedInMember.class::isInstance)
                 .map(MixedInMember.class::cast)
-                .filter(member->member.getMixinType() == onType)
+                .filter(member->member.getMixinType().getFeatureIdentifier().equals(mixinSpec.getFeatureIdentifier()))
                 .findAny();
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index 9c522b3..a0a476a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -25,8 +25,6 @@ import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import javax.annotation.Nullable;
-
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.PromptStyle;
@@ -37,6 +35,7 @@ import org.apache.isis.applib.value.Clob;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.collections.CanVector;
 import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.consent.InteractionResultSet;
@@ -53,7 +52,6 @@ import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.memento.ActionMemento;
-import org.apache.isis.core.metamodel.specloader.specimpl.MixedInMember;
 
 import static org.apache.isis.commons.internal.base._NullSafe.stream;
 
@@ -309,10 +307,6 @@ public interface ObjectAction extends ObjectMember {
             return className + "-" + actionId;
         }
 
-        public static String descriptionOf(final ObjectAction action) {
-            return action.getDescription();
-        }
-
         public static ActionLayout.Position actionLayoutPositionOf(final ObjectAction action) {
             final ActionPositionFacet layoutFacet = action.getFacet(ActionPositionFacet.class);
             return layoutFacet != null ? layoutFacet.position() : ActionLayout.Position.BELOW;
@@ -371,19 +365,20 @@ public interface ObjectAction extends ObjectMember {
             return promptStyle;
         }
 
-        public static Optional<String> targetNameFor(
-                final ObjectAction owningAction,
-                final @Nullable ManagedObject mixedInAdapter) {
+        public static String friendlyNameFor(
+                final @NonNull ObjectAction action,
+                final @NonNull InteractionHead head) {
 
-            if(mixedInAdapter != null) {
-                final ObjectSpecification onType = owningAction.getOnType();
-                final ObjectSpecification mixedInSpec = mixedInAdapter.getSpecification();
-                final Optional<String> mixinName = mixedInSpec.getMixedInMember(onType)
-                        .map(MixedInMember::getName);
+            val mixeeAdapter = head.getMixedIn().orElse(null);
 
-                return mixinName;
+            if(mixeeAdapter != null) {
+                val mixinSpec = action.getOnType();
+                val ownerSpec = mixeeAdapter.getSpecification();
+                return ownerSpec.lookupMixedInMember(mixinSpec)
+                        .map(mixedInMember->mixedInMember.getFriendlyName(mixeeAdapter.asProvider()))
+                        .orElseThrow(_Exceptions::unexpectedCodeReach);
             }
-            return Optional.empty();
+            return action.getFriendlyName(head::getOwner);
         }
     }
 
@@ -451,12 +446,12 @@ public interface ObjectAction extends ObjectMember {
 
         private static class ChoicesFrom implements Predicate<ObjectAction> {
             private final @NonNull String memberId;
-            private final @NonNull String memberName;
+//            private final @NonNull String memberName;
 
             public ChoicesFrom(final @NonNull ObjectAssociation objectAssociation) {
 
                 this.memberId = _Strings.nullToEmpty(objectAssociation.getId()).toLowerCase();
-                this.memberName = _Strings.nullToEmpty(objectAssociation.getName()).toLowerCase();
+//                this.memberName = _Strings.nullToEmpty(objectAssociation.getName()).toLowerCase();
             }
 
             @Override
@@ -470,8 +465,9 @@ public interface ObjectAction extends ObjectMember {
                     return false;
                 }
                 val memberNameLowerCase = choicesFromMemberName.toLowerCase();
-                return Objects.equals(memberName, memberNameLowerCase)
-                        || Objects.equals(memberId, memberNameLowerCase);
+//                return Objects.equals(memberName, memberNameLowerCase)
+//                        || Objects.equals(memberId, memberNameLowerCase);
+                return Objects.equals(memberId, memberNameLowerCase);
             }
 
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
index 3fc4cd4..f5dfaa8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.spec.feature;
 
+import java.util.Optional;
 import java.util.function.Predicate;
 
 import javax.annotation.Nullable;
@@ -40,7 +41,8 @@ import lombok.NonNull;
 /**
  * Analogous to {@link ObjectAssociation}.
  */
-public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
+public interface ObjectActionParameter
+extends ObjectFeature, CurrentHolder {
 
     /**
      * Owning {@link ObjectAction}.
@@ -69,7 +71,7 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
      * </ul>
      */
     @Override
-    String getName();
+    Optional<String> getStaticFriendlyName();
 
     // internal API
     ActionArgValidityContext createProposedArgumentInteractionContext(
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
index 70f8314..b976585 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
@@ -50,7 +50,7 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
     /**
      * As per {@link #get(ManagedObject, InteractionInitiatedBy)}, with {@link InteractionInitiatedBy#USER}.
      */
-    public default ManagedObject get(ManagedObject owner) {
+    public default ManagedObject get(final ManagedObject owner) {
         return get(owner, InteractionInitiatedBy.USER);
     }
 
@@ -196,7 +196,7 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
             getFrom(associationsByGroup, LAYOUT_DEFAULT_GROUP).add(association);
         }
 
-        private static List<ObjectAssociation> getFrom(Map<String, List<ObjectAssociation>> associationsByGroup, final String groupName) {
+        private static List<ObjectAssociation> getFrom(final Map<String, List<ObjectAssociation>> associationsByGroup, final String groupName) {
             List<ObjectAssociation> list = associationsByGroup.get(groupName);
             if(list == null) {
                 list = _Lists.newArrayList();
@@ -205,4 +205,6 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
             return list;
         }
     }
+
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java
index e0bd97e..5994700 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectFeature.java
@@ -19,6 +19,9 @@
 
 package org.apache.isis.core.metamodel.spec.feature;
 
+import java.util.Optional;
+import java.util.function.Supplier;
+
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
@@ -47,40 +50,45 @@ public interface ObjectFeature extends Specification {
     String getId();
 
     /**
-     * Return the name for this member - the field or action. This is based on
-     * the name of this member.
+     * Returns the (translated friendly) name for this member - the field or action.
+     * If not specified, defaults to the java-source-code name of this member.
+     *
+     * @apiNote argument is a {@link Supplier}, because the {@link ManagedObject}
+     * is only required when the name is provided imperatively and domain-object
+     * retrieval might be expensive
      *
      * @see #getFeatureIdentifier()
-     * @deprecated TODO[ISIS-1720] must take ManagedObject as an argument
      */
-    @Deprecated
-    String getName();
+    String getFriendlyName(Supplier<ManagedObject> domainObjectProvider);
 
     /**
-     * Returns the (friendly) name for this member - the field or action.
-     * If not specified, defaults to the java-source code name of this member.
+     * Optionally returns the (translated friendly) name for this member -
+     * the field or action, based on whether the name is provided statically
+     * and not imperatively.
+     * <p>
+     * If not specified, defaults to the java-source-code name of this member.
      *
      * @see #getFeatureIdentifier()
      */
-    default String getName(final ManagedObject domainObject) {
-        return getName();
-    }
+    Optional<String> getStaticFriendlyName();
 
     /**
-     * Returns a description of how the member is used - this complements the
+     * Returns a (translated) description of how the member is used - this complements the
      * help text.
-     * @deprecated TODO[ISIS-1720] must take ManagedObject as an argument
+     *
+     * @apiNote argument is a {@link Supplier}, because the {@link ManagedObject}
+     * is only required when the description is provided imperatively and domain-object
+     * retrieval might be expensive
+     *
      */
-    @Deprecated
-    String getDescription();
+    String getDescription(final Supplier<ManagedObject> domainObjectProvider);
 
     /**
-     * Returns a description of how the member is used - this complements the
-     * help text.
+     * Optionally returns the (translated) description of how the member is used,
+     * based on whether the description is provided statically
+     * and not imperatively.
      */
-    default String getDescription(final ManagedObject domainObject) {
-        return getDescription();
-    }
+    Optional<String> getStaticDescription();
 
     /**
      * The specification of the underlying type.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java
index 6e2dd7f..72b25cd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java
@@ -29,7 +29,11 @@ import org.apache.isis.core.metamodel.spec.feature.memento.PropertyMemento;
  * Provides reflective access to a field on a domain object that is used to
  * reference another domain object.
  */
-public interface OneToOneAssociation extends ObjectAssociation, OneToOneFeature, MutableCurrentHolder {
+public interface OneToOneAssociation
+extends
+    ObjectAssociation,
+    OneToOneFeature,
+    MutableCurrentHolder {
 
     /**
      * Initialise this field in the specified object with the specified
@@ -40,8 +44,6 @@ public interface OneToOneAssociation extends ObjectAssociation, OneToOneFeature,
      */
     void initAssociation(ManagedObject inObject, ManagedObject associate);
 
-
-
     /**
      * Determines if the specified reference is valid for setting this field in
      * the specified object, represented as a {@link Consent}.
@@ -51,7 +53,6 @@ public interface OneToOneAssociation extends ObjectAssociation, OneToOneFeature,
             final ManagedObject proposedAdapter,
             final InteractionInitiatedBy interactionInitiatedBy);
 
-
     /**
      * Returns true if calculated from other data in the object, that is, should
      * not be persisted.
@@ -60,9 +61,7 @@ public interface OneToOneAssociation extends ObjectAssociation, OneToOneFeature,
         return containsFacet(SnapshotExcludeFacet.class);
     }
 
-
-
-    default String getCssClass(String prefix) {
+    default String getCssClass(final String prefix) {
         final String ownerObjectType = getOnType().getLogicalTypeName().replace(".", "-");
         final String memberId = getFeatureIdentifier().getMemberLogicalName();
         return prefix + ownerObjectType + "-" + memberId;
@@ -75,4 +74,11 @@ public interface OneToOneAssociation extends ObjectAssociation, OneToOneFeature,
         return PropertyMemento.forProperty(this);
     }
 
+    /**
+     * When rendering a domain-object collection as table,
+     * the table's column names are inferred
+     * from the property column-names.
+     */
+    String getColumnName();
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index 94316eb..01b5631 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@ -74,14 +74,14 @@ implements HasMetaModelContext {
 
         private final Set<Method> methodsRemaining;
 
-        private FacetedMethodsMethodRemover(final Class<?> introspectedClass, Method[] methods) {
+        private FacetedMethodsMethodRemover(final Class<?> introspectedClass, final Method[] methods) {
             this.methodsRemaining = Stream.of(methods)
                     .filter(_NullSafe::isPresent)
                     .collect(Collectors.toCollection(_Sets::newConcurrentHashSet));
         }
 
         @Override
-        public void removeMethods(Predicate<Method> removeIf, Consumer<Method> onRemoval) {
+        public void removeMethods(final Predicate<Method> removeIf, final Consumer<Method> onRemoval) {
             methodsRemaining.removeIf(method -> {
                 val doRemove = removeIf.test(method);
                 if(doRemove) {
@@ -92,7 +92,7 @@ implements HasMetaModelContext {
         }
 
         @Override
-        public void removeMethod(Method method) {
+        public void removeMethod(final Method method) {
             if(method==null) {
                 return;
             }
@@ -252,7 +252,7 @@ implements HasMetaModelContext {
      * Since the value properties and collections have already been processed,
      * this will pick up the remaining reference properties.
      */
-    private void findAndRemovePropertyAccessorsAndCreateCorrespondingFacetedMethods(Consumer<FacetedMethod> onNewField) {
+    private void findAndRemovePropertyAccessorsAndCreateCorrespondingFacetedMethods(final Consumer<FacetedMethod> onNewField) {
         val propertyAccessors = _Lists.<Method>newArrayList();
         getFacetProcessor().findAndRemovePropertyAccessors(methodRemover, propertyAccessors);
 
@@ -540,7 +540,7 @@ implements HasMetaModelContext {
             final Class<?> returnType,
             final CanBeVoid canBeVoid,
             final int paramCount,
-            Consumer<Method> onMatch) {
+            final Consumer<Method> onMatch) {
 
         val filter = MethodUtil.Predicates.prefixed(prefix, returnType, canBeVoid, paramCount);
         methodRemover.removeMethods(filter, onMatch);
@@ -553,7 +553,7 @@ implements HasMetaModelContext {
      *
      * @param method
      */
-    private boolean isMixinMain(Method method) {
+    private boolean isMixinMain(final Method method) {
         val mixinFacet = inspectedTypeSpec.lookupNonFallbackFacet(MixinFacet.class)
                 .orElse(null);
         if(mixinFacet==null) {
@@ -563,13 +563,14 @@ implements HasMetaModelContext {
             // members are not introspected yet, so make a guess
             return mixinFacet.isCandidateForMain(method);
         }
-        val mixinMember = inspectedTypeSpec.getMixedInMember(inspectedTypeSpec);
-        if(!mixinMember.isPresent()) {
-            return false;
-        }
-        val actionMethod_ofMixinMember = ((ObjectActionMixedIn)mixinMember.get())
-                .getFacetedMethod().getMethod();
-        return method.equals(actionMethod_ofMixinMember);
+
+        return inspectedTypeSpec
+                .lookupMixedInMember(inspectedTypeSpec)
+                .map(ObjectActionMixedIn.class::cast)
+                .map(ObjectActionMixedIn::getFacetedMethod)
+                .map(FacetedMethod::getMethod)
+                .map(method::equals)
+                .orElse(false);
     }
 
     // ////////////////////////////////////////////////////////////////////////////
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index 9d91fd1..8f5e5cd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -34,6 +34,7 @@ import org.apache.isis.commons.collections.CanVector;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.consent.InteractionResultSet;
@@ -153,7 +154,7 @@ implements ObjectAction {
     }
 
     @Override
-    public ActionInteractionHead interactionHead(@NonNull ManagedObject actionOwner) {
+    public ActionInteractionHead interactionHead(@NonNull final ManagedObject actionOwner) {
         return ActionInteractionHead.of(this, actionOwner, actionOwner);
     }
 
@@ -209,7 +210,8 @@ implements ObjectAction {
     @Override
     public ObjectActionParameter getParameterByName(final String paramName) {
         return getParameters().stream()
-                .filter(param->Objects.equals(paramName, param.getName()))
+                .filter(param->Objects.equals(paramName, param.getStaticFriendlyName()
+                        .orElseThrow(_Exceptions::unexpectedCodeReach)))
                 .findAny()
                 .orElse(null);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
index f255021..12820a4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
@@ -20,6 +20,8 @@
 package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import java.util.ArrayList;
+import java.util.Optional;
+import java.util.function.Supplier;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.exceptions.unrecoverable.DomainModelException;
@@ -61,7 +63,9 @@ import lombok.NonNull;
 import lombok.val;
 
 public abstract class ObjectActionParameterAbstract
-implements ObjectActionParameter, HasFacetHolder {
+implements
+    ObjectActionParameter,
+    HasFacetHolder {
 
     private final FeatureType featureType;
     private final int number;
@@ -128,26 +132,42 @@ implements ObjectActionParameter, HasFacetHolder {
 
     @Override
     public String getId() {
-        return StringExtensions.asCamelLowerFirst(getName());
+        return lookupFacet(ParamNamedFacet.class)
+        .map(ParamNamedFacet::text)
+        .map(StringExtensions::asCamelLowerFirst)
+//                .orElseThrow(()->_Exceptions
+//                        .unrecoverableFormatted("action parameters must have a ParamNamedFacet %s", this));
+        .orElseGet(()->StringExtensions.asCamelLowerFirst(staticFriendlyName()));
     }
 
     @Override
-    public String getName() {
+    public String getFriendlyName(final Supplier<ManagedObject> domainObjectProvider) {
+        //as we don't support imperative naming for parameters yet ..
+        return staticFriendlyName();
+    }
+
+    @Override
+    public Optional<String> getStaticFriendlyName() {
+        return Optional.of(staticFriendlyName());
+    }
 
-        val name = lookupFacet(ParamNamedFacet.class)
+
+    private String staticFriendlyName() {
+        return lookupFacet(ParamNamedFacet.class)
         .map(ParamNamedFacet::translated)
-        .orElse(null);
+//
+//        .orElseThrow(()->_Exceptions
+//                .unrecoverableFormatted("action parameters must have a ParamNamedFacet %s", this));
+        .orElseGet(()->{
+            val singularName = getSpecification().getSingularName();
+            val parameters = getAction().getParameters(this::equalsShortIdentifier);
+            if (parameters.isCardinalityOne()) {
+                return singularName;
+            }
+            final int indexOf = parameters.indexOf(this);
+            return singularName + " " + (indexOf + 1);
 
-        if (name!=null) {
-            return name;
-        }
-        val singularName = getSpecification().getSingularName();
-        val parameters = getAction().getParameters(this::equalsShortIdentifier);
-        if (parameters.isCardinalityOne()) {
-            return singularName;
-        }
-        final int indexOf = parameters.indexOf(this);
-        return singularName + " " + (indexOf + 1);
+        });
     }
 
     private boolean equalsShortIdentifier(final ObjectActionParameter objParam) {
@@ -158,7 +178,17 @@ implements ObjectActionParameter, HasFacetHolder {
     }
 
     @Override
-    public String getDescription() {
+    public String getDescription(final Supplier<ManagedObject> domainObjectProvider) {
+        //as we don't support imperative naming for parameters yet ..
+        return staticDescription();
+    }
+
+    @Override
+    public Optional<String> getStaticDescription() {
+        return Optional.of(staticDescription());
+    }
+
+    private String staticDescription() {
         return lookupFacet(ParamDescribedFacet.class)
         .map(ParamDescribedFacet::translated)
         .orElse("");
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
index b7ffcfa..659989e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
@@ -20,8 +20,10 @@
 package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import java.util.Objects;
+import java.util.Optional;
 import java.util.UUID;
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
@@ -118,16 +120,9 @@ implements
     }
 
     // -- Name, Description, Help (convenience for facets)
-    /**
-     * Return the default label for this member. This is based on the name of
-     * this member.
-     *
-     * @see #getId()
-     */
-    @Override
-    public String getName() {
 
-        final ManagedObject owner = null; //TODO[ISIS-1720] must take ManagedObject (owner) as an argument
+    @Override
+    public String getFriendlyName(final Supplier<ManagedObject> domainObjectProvider) {
 
         val namedFacet = getFacet(MemberNamedFacet.class);
 
@@ -138,23 +133,43 @@ implements
         return namedFacet
             .getSpecialization()
             .fold(  textFacet->textFacet.translated(),
-                    textFacet->textFacet.textElseNull(owner));
+                    textFacet->textFacet.textElseNull(domainObjectProvider.get()));
     }
 
     @Override
-    public String getDescription() {
+    public Optional<String> getStaticFriendlyName() {
+        return lookupFacet(MemberNamedFacet.class)
+        .map(MemberNamedFacet::getSpecialization)
+        .flatMap(specialization->specialization
+                .fold(
+                        textFacet->Optional.of(textFacet.translated()),
+                        textFacet->Optional.empty()));
+    }
 
-        final ManagedObject owner = null; //TODO[ISIS-1720] must take ManagedObject (owner) as an argument
+
+    @Override
+    public String getDescription(final Supplier<ManagedObject> domainObjectProvider) {
 
         return lookupFacet(MemberDescribedFacet.class)
         .map(MemberDescribedFacet::getSpecialization)
         .map(specialization->specialization
                 .fold(textFacet->textFacet.translated(),
-                      textFacet->textFacet.textElseNull(owner)))
+                      textFacet->textFacet.textElseNull(domainObjectProvider.get())))
         .orElse(null);
     }
 
     @Override
+    public Optional<String> getStaticDescription() {
+        return lookupFacet(MemberDescribedFacet.class)
+                .map(MemberDescribedFacet::getSpecialization)
+                .flatMap(specialization->specialization
+                        .fold(
+                                textFacet->Optional.of(textFacet.translated()),
+                                textFacet->Optional.empty()));
+    }
+
+
+    @Override
     public String getHelp() {
         final HelpFacet facet = getFacet(HelpFacet.class);
         return facet.value();
@@ -309,7 +324,9 @@ implements
 
     @Override
     public String toString() {
-        return String.format("id=%s,name='%s'", getId(), getName());
+        return getStaticFriendlyName()
+                .map(name->String.format("id=%s,name='%s'", getId(), name))
+                .orElseGet(()->String.format("id=%s,name=imperative", getId()));
     }
 
     // -- Dependencies
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
index 13849c9..caa7495 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
@@ -41,7 +41,8 @@ import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import lombok.val;
 
 public class OneToManyAssociationDefault
-extends ObjectAssociationAbstract implements OneToManyAssociation {
+extends ObjectAssociationAbstract
+implements OneToManyAssociation {
 
     public static OneToManyAssociationDefault forMethod(final FacetedMethod facetedMethod) {
         return new OneToManyAssociationDefault(
@@ -153,8 +154,8 @@ extends ObjectAssociationAbstract implements OneToManyAssociation {
 
     @Override
     public Can<ManagedObject> getAutoComplete(
-            ManagedObject object,
-            String searchArg,
+            final ManagedObject object,
+            final String searchArg,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         return Can.empty();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
index 90a5105..ecd3f7f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
@@ -75,7 +75,16 @@ implements OneToOneAssociation {
         super(featureIdentifier, facetedMethod, FeatureType.PROPERTY, objectSpec);
     }
 
-    // -- visible, usable
+    // -- NAMED
+
+    @Override
+    public String getColumnName() {
+        //TODO[ISIS-1720] use a synthetic facet inferred from any static names instead
+        return getStaticFriendlyName()
+                .orElseGet(()->getFeatureIdentifier().getMemberNaturalName());
+    }
+
+    // -- VISIBLE, USABLE
 
     @Override
     public VisibilityContext createVisibleInteractionContext(
@@ -96,9 +105,8 @@ implements OneToOneAssociation {
                 headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where);
     }
 
+    // -- VALIDITY
 
-
-    // -- Validity
     private ValidityContext createValidateInteractionContext(
             final ManagedObject ownerAdapter,
             final ManagedObject proposedToReferenceAdapter,
@@ -126,9 +134,8 @@ implements OneToOneAssociation {
         return InteractionUtils.isValidResult(this, validityContext);
     }
 
+    // -- INIT
 
-
-    // -- init
     @Override
     public void initAssociation(
             final ManagedObject ownerAdapter,
@@ -140,9 +147,7 @@ implements OneToOneAssociation {
         }
     }
 
-
-
-    // -- Access (get, isEmpty)
+    // -- ACCESS (get, isEmpty)
 
     @Override
     public ManagedObject get(
@@ -165,7 +170,7 @@ implements OneToOneAssociation {
         return get(ownerAdapter, interactionInitiatedBy) == null;
     }
 
-    // -- Set
+    // -- ACCESS (set)
 
     /**
      * Sets up the {@link Command}, then delegates to the appropriate facet
@@ -214,9 +219,8 @@ implements OneToOneAssociation {
         return propertyClearFacet.clearProperty(this, ownerAdapter, interactionInitiatedBy);
     }
 
+    // -- DEFAULTS
 
-
-    // -- defaults
     @Override
     public ManagedObject getDefault(final ManagedObject ownerAdapter) {
         PropertyDefaultFacet propertyDefaultFacet = lookupNonFallbackFacet(PropertyDefaultFacet.class)
@@ -246,9 +250,8 @@ implements OneToOneAssociation {
         }
     }
 
+    // -- CHOICES AND AUTO-COMPLETE
 
-
-    // -- choices and autoComplete
     @Override
     public boolean hasChoices() {
         return getFacet(PropertyChoicesFacet.class) != null;
@@ -298,8 +301,6 @@ implements OneToOneAssociation {
         return propertyAutoCompleteFacet != null? propertyAutoCompleteFacet.getMinLength(): MinLengthUtil.MIN_LENGTH_DEFAULT;
     }
 
-
-
     /**
      * Internal API
      */
@@ -312,8 +313,7 @@ implements OneToOneAssociation {
                 .asCommandDto(interactionId, Can.ofSingleton(head), this, valueAdapterOrNull));
     }
 
-
-    // -- toString
+    // -- OBJECT CONTRACT
 
     @Override
     public String toString() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
index 6974396..4519a7f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
@@ -439,7 +439,7 @@ public class XmlSnapshot implements Snapshot {
         }
 
         // take the first field name from the list, and remove
-        final String fieldName = (String) names.elementAt(0);
+        final String fieldName = names.elementAt(0);
         names.removeElementAt(0);
 
         if (log.isDebugEnabled()) {
@@ -473,7 +473,7 @@ public class XmlSnapshot implements Snapshot {
             }
             return false;
         }
-        final Element xmlFieldElement = (Element) xmlFieldElements.elementAt(0);
+        final Element xmlFieldElement = xmlFieldElements.elementAt(0);
 
         if (names.size() == 0 && annotation != null) {
             // nothing left in the path, so we will apply the annotation now
@@ -630,20 +630,20 @@ public class XmlSnapshot implements Snapshot {
             log.debug("objectToElement({})", log("object", adapter));
         }
 
-        final ObjectSpecification nos = adapter.getSpecification();
+        final ObjectSpecification spec = adapter.getSpecification();
 
         if (log.isDebugEnabled()) {
             log.debug("objectToElement(NO): create element and isis:title");
         }
-        final Element element = schema.createElement(getXmlDocument(), nos.getShortIdentifier(),
-                nos.getFullIdentifier(), nos.getSingularName(), nos.getPluralName());
+        final Element element = schema.createElement(getXmlDocument(), spec.getShortIdentifier(),
+                spec.getFullIdentifier(), spec.getSingularName(), spec.getPluralName());
         isisMetaModel.appendIsisTitle(element, adapter.titleString());
 
         if (log.isDebugEnabled()) {
             log.debug("objectToElement(NO): create XS element for Isis class");
         }
         final Element xsElement = schema.createXsElementForNofClass(getXsdDocument(), element, topLevelElementWritten,
-                FacetUtil.getFacetsByType(nos));
+                FacetUtil.getFacetsByType(spec));
 
         // hack: every element in the XSD schema apart from first needs minimum
         // cardinality setting.
@@ -653,7 +653,7 @@ public class XmlSnapshot implements Snapshot {
 
         isisMetaModel.setAttributesForClass(element, oidAsString(adapter).toString());
 
-        final List<ObjectAssociation> fields = nos.streamAssociations(MixedIn.INCLUDED)
+        final List<ObjectAssociation> fields = spec.streamAssociations(MixedIn.INCLUDED)
                 .collect(Collectors.toList());
         if (log.isDebugEnabled()) {
             log.debug("objectToElement(NO): processing fields");
@@ -668,7 +668,7 @@ public class XmlSnapshot implements Snapshot {
 
             // Skip field if we have seen the name already
             for (int j = 0; j < i; j++) {
-                if (Objects.equals(fieldName, fields.get(i).getName())) {
+                if (Objects.equals(fieldName, fields.get(i).getFriendlyName(adapter.asProvider()))) {
                     log.debug("objectToElement(NO): {} SKIPPED", log("field", fieldName));
                     continue eachField;
                 }
@@ -744,7 +744,7 @@ public class XmlSnapshot implements Snapshot {
                 }
 
                 final OneToOneAssociation oneToOneAssociation = ((OneToOneAssociation) field);
-                final String fullyQualifiedClassName = nos.getFullIdentifier();
+                final String fullyQualifiedClassName = spec.getFullIdentifier();
                 final Element xmlReferenceElement = xmlFieldElement; // more meaningful locally scoped name
 
                 ManagedObject referencedObjectAdapter;
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java
index e71da62..b673943 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java
@@ -90,7 +90,7 @@ public class ObjectActionLayoutXmlDefaultTest {
                 will(returnValue(facet));
             }
         });
-        assertThat(action.getName(), is(equalTo(name)));
+        assertThat(action.getStaticFriendlyName().get(), is(equalTo(name)));
     }
 
     @Test
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
index 62c632f..e077def 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
@@ -106,7 +106,7 @@ public class OneToManyAssociationDefaultTest {
     @Test
     public void name() {
         expectPeerToReturnNamedFacet();
-        assertThat(association.getName(), is(equalTo("My name")));
+        assertThat(association.getStaticFriendlyName().get(), is(equalTo("My name")));
     }
 
     private void allowingPeerToReturnCollectionType() {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getId_and_getName.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getId_and_getName.java
index ebe4eb9..1450192 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getId_and_getName.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getId_and_getName.java
@@ -50,21 +50,16 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
     @Rule
     public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
 
-    @Mock
-    private ObjectActionDefault parentAction;
-    @Mock
-    private TypedHolder actionParamPeer;
-    @Mock
-    private ParamNamedFacet namedFacet;
-
-    @Mock
-    private ObjectSpecification stubSpecForString;
-    @Mock
-    private ObjectActionParameter stubObjectActionParameterString;
-    @Mock
-    private ObjectActionParameter stubObjectActionParameterString2;
-
-    private static final class ObjectActionParameterAbstractToTest extends ObjectActionParameterAbstract {
+    @Mock private ObjectActionDefault parentAction;
+    @Mock private TypedHolder actionParamPeer;
+    @Mock private ParamNamedFacet namedFacet;
+
+    @Mock private ObjectSpecification stubSpecForString;
+    @Mock private ObjectActionParameter stubObjectActionParameterString;
+    @Mock private ObjectActionParameter stubObjectActionParameterString2;
+
+    private static final class ObjectActionParameterAbstractToTest
+    extends ObjectActionParameterAbstract {
         private ObjectActionParameterAbstractToTest(final int number, final ObjectActionDefault objectAction, final TypedHolder peer) {
             super(FeatureType.ACTION_PARAMETER_SCALAR, number, objectAction, peer);
         }
@@ -135,8 +130,9 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
                 oneOf(actionParamPeer).getFacet(ParamNamedFacet.class);
                 will(returnValue(namedFacet));
 
-                atLeast(1).of(namedFacet).translated();
-                will(returnValue("Some parameter name"));
+                oneOf(namedFacet).text();
+                will(returnValue("someParameterName"));
+
             }
         });
 
@@ -158,7 +154,7 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
             }
         });
 
-        assertThat(objectActionParameter.getName(), is("Some parameter name"));
+        assertThat(objectActionParameter.getStaticFriendlyName().get(), is("Some parameter name"));
     }
 
     @Test
@@ -177,7 +173,7 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
             }
         });
 
-        assertThat(objectActionParameter.getName(), is("string"));
+        assertThat(objectActionParameter.getStaticFriendlyName().get(), is("string"));
     }
 
     @Test
@@ -188,7 +184,7 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
 
         context.checking(new Expectations() {
             {
-                oneOf(actionParamPeer).getFacet(ParamNamedFacet.class);
+                allowing(actionParamPeer).getFacet(ParamNamedFacet.class);
                 will(returnValue(null));
 
                 oneOf(parentAction).getParameters(with(Expectations.<Predicate<ObjectActionParameter>>anything()));
@@ -207,7 +203,7 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
 
         context.checking(new Expectations() {
             {
-                oneOf(actionParamPeer).getFacet(ParamNamedFacet.class);
+                allowing(actionParamPeer).getFacet(ParamNamedFacet.class);
                 will(returnValue(null));
 
                 oneOf(parentAction).getParameters(with(Expectations.<Predicate<ObjectActionParameter>>anything()));
@@ -215,7 +211,7 @@ public class ObjectActionParameterAbstractTest_getId_and_getName {
             }
         });
 
-        assertThat(objectActionParameter.getName(), is("string 2"));
+        assertThat(objectActionParameter.getStaticFriendlyName().get(), is("string 2"));
     }
 
 }
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java
index 4c826d9..6b22908 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoFactoryDefault.java
@@ -18,7 +18,15 @@
  */
 package org.apache.isis.core.runtimeservices.command;
 
-import lombok.val;
+import java.util.UUID;
+
+import javax.annotation.Priority;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
@@ -27,6 +35,7 @@ import org.apache.isis.applib.services.user.UserService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.applib.util.schema.CommonDtoUtils;
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
@@ -42,13 +51,8 @@ import org.apache.isis.schema.cmd.v2.CommandDto;
 import org.apache.isis.schema.cmd.v2.PropertyDto;
 import org.apache.isis.schema.common.v2.InteractionType;
 import org.apache.isis.schema.common.v2.OidsDto;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Service;
 
-import javax.annotation.Priority;
-import javax.inject.Inject;
-import javax.inject.Named;
-import java.util.UUID;
+import lombok.val;
 
 /**
  * The design of this service is similar to
@@ -124,12 +128,14 @@ public class CommandDtoFactoryDefault implements CommandDtoFactory {
 
             val paramDto = actionParameter.getFeatureType() == FeatureType.ACTION_PARAMETER_COLLECTION
                     ? CommonDtoUtils.newParamDtoNonScalar(
-                            actionParameter.getName(),
+                            actionParameter.getStaticFriendlyName()
+                                .orElseThrow(_Exceptions::unexpectedCodeReach),
                             paramTypeOrElementType,
                             arg,
                             bookmarkService)
                     : CommonDtoUtils.newParamDto(
-                            actionParameter.getName(),
+                            actionParameter.getStaticFriendlyName()
+                                .orElseThrow(_Exceptions::unexpectedCodeReach),
                             paramTypeOrElementType,
                             arg,
                             bookmarkService);
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index 027f117..000a5d4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -121,15 +121,13 @@ implements MemberExecutorService {
         log.debug("about to invoke action {}", actionId);
 
         val targetAdapter = head.getTarget();
-        val mixedInAdapter = head.getMixedIn().orElse(null);
-
         val targetPojo = UnwrapUtil.single(targetAdapter);
 
         val argumentPojos = argumentAdapters.stream()
                 .map(UnwrapUtil::single)
                 .collect(_Lists.toUnmodifiable());
 
-        val targetMemberName = targetNameFor(owningAction, mixedInAdapter);
+        val targetMemberName = ObjectAction.Util.friendlyNameFor(owningAction, head);
         val targetClass = CommandUtil.targetClassNameFor(targetAdapter);
 
         val actionInvocation =
@@ -203,7 +201,7 @@ implements MemberExecutorService {
         val target = UnwrapUtil.single(targetManagedObject);
         val argValue = UnwrapUtil.single(newValueAdapter);
 
-        val targetMemberName = CommandUtil.targetMemberNameFor(owningProperty);
+        val targetMemberName = owningProperty.getFriendlyName(head::getTarget);
         val targetClass = CommandUtil.targetClassNameFor(targetManagedObject);
 
         val propertyEdit = new PropertyEdit(interaction, propertyId, target, argValue, targetMemberName, targetClass);
@@ -240,12 +238,9 @@ implements MemberExecutorService {
 
     // -- HELPER
 
-    private static String targetNameFor(ObjectAction owningAction, ManagedObject mixedInAdapter) {
-        return ObjectAction.Util.targetNameFor(owningAction, mixedInAdapter)
-                .orElseGet(()->CommandUtil.targetMemberNameFor(owningAction));
-    }
-
-    private void setCommandResultIfEntity(final Command command, final ManagedObject resultAdapter) {
+    private void setCommandResultIfEntity(
+            final Command command,
+            final ManagedObject resultAdapter) {
         if(command.getResult() != null) {
             // don't trample over any existing result, eg subsequent mixins.
             return;
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
index d20177d..cc9068b 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
@@ -283,7 +283,7 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
                 val service = serviceAndAction.getServiceAdapter();
                 final String logicalTypeName = serviceAndAction.getServiceAdapter().getSpecification().getLogicalTypeName();
                 ServiceActionLayoutData action = new ServiceActionLayoutData(logicalTypeName, objectAction.getId());
-                action.setNamed(objectAction.getName(service));
+                action.setNamed(objectAction.getFriendlyName(service.asProvider()));
                 menuSection.getServiceActions().add(action);
             }
             if(!menuSection.getServiceActions().isEmpty()) {
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/AbstractCollectionInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/AbstractCollectionInvocationHandler.java
index 6f0024a..b723060 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/AbstractCollectionInvocationHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/AbstractCollectionInvocationHandler.java
@@ -33,13 +33,11 @@ extends DelegatingInvocationHandlerDefault<C> {
     private final List<Method> interceptedMethods = _Lists.newArrayList();
     private final List<Method> vetoedMethods = _Lists.newArrayList();
 
-    private final String collectionName;
     private final OneToManyAssociation oneToManyAssociation;
     private final T domainObject;
 
     public AbstractCollectionInvocationHandler(
             final C collectionOrMapToProxy,
-            final String collectionName,
             final DomainObjectInvocationHandler<T> handler,
             final OneToManyAssociation otma) {
 
@@ -47,7 +45,6 @@ extends DelegatingInvocationHandlerDefault<C> {
                 collectionOrMapToProxy,
                 handler.getSyncControl());
 
-        this.collectionName = collectionName;
         this.oneToManyAssociation = otma;
         this.domainObject = handler.getDelegate();
     }
@@ -62,10 +59,6 @@ extends DelegatingInvocationHandlerDefault<C> {
         return method;
     }
 
-    public String getCollectionName() {
-        return collectionName;
-    }
-
     public OneToManyAssociation getCollection() {
         return oneToManyAssociation;
     }
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/CollectionInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/CollectionInvocationHandler.java
index c8230f4..407cb69 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/CollectionInvocationHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/CollectionInvocationHandler.java
@@ -29,11 +29,10 @@ class CollectionInvocationHandler<T, R> extends AbstractCollectionInvocationHand
 
     public CollectionInvocationHandler(
             final R collectionToProxy,
-            final String collectionName,
             final DomainObjectInvocationHandler<T> handler,
             final OneToManyAssociation otma) {
 
-        super(collectionToProxy, collectionName, handler, otma);
+        super(collectionToProxy, handler, otma);
 
         try {
             intercept(ObjectExtensions.getMethod(collectionToProxy, "contains", Object.class));
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
index 0c2b21a..0f198a8 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
@@ -173,11 +173,11 @@ extends DelegatingInvocationHandlerDefault<T> {
         }
 
         val objectMember = targetSpec.getMemberElseFail(method);
-        val memberName = objectMember.getName();
+        val memberId = objectMember.getId();
 
         val intent = ImperativeFacet.getIntent(objectMember, method);
         if(intent == Intent.CHECK_IF_HIDDEN || intent == Intent.CHECK_IF_DISABLED) {
-            throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'", memberName));
+            throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'", memberId));
         }
 
         if (intent == Intent.DEFAULTS || intent == Intent.CHOICES_OR_AUTOCOMPLETE) {
@@ -187,7 +187,7 @@ extends DelegatingInvocationHandlerDefault<T> {
         if (objectMember.isOneToOneAssociation()) {
 
             if (intent == Intent.CHECK_IF_VALID || intent == Intent.MODIFY_PROPERTY_SUPPORTING) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method for '%s'; use only property accessor/mutator", memberName));
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method for '%s'; use only property accessor/mutator", memberId));
             }
 
             final OneToOneAssociation otoa = (OneToOneAssociation) objectMember;
@@ -203,19 +203,19 @@ extends DelegatingInvocationHandlerDefault<T> {
         if (objectMember.isOneToManyAssociation()) {
 
             if (intent == Intent.CHECK_IF_VALID) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only collection accessor/mutator", memberName));
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only collection accessor/mutator", memberId));
             }
 
             final OneToManyAssociation otma = (OneToManyAssociation) objectMember;
             if (intent == Intent.ACCESSOR) {
-                return handleGetterMethodOnCollection(targetAdapter, args, otma, memberName);
+                return handleGetterMethodOnCollection(targetAdapter, args, otma, memberId);
             }
         }
 
         if (objectMember instanceof ObjectAction) {
 
             if (intent == Intent.CHECK_IF_VALID) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only the 'invoke' method", memberName));
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only the 'invoke' method", memberId));
             }
 
             val objectAction = (ObjectAction) objectMember;
@@ -239,7 +239,7 @@ extends DelegatingInvocationHandlerDefault<T> {
                         return handleGetterMethodOnProperty(mixeeAdapter, new Object[0], (OneToOneAssociation)mixinMember);
                     }
                     if(mixinMember instanceof OneToManyAssociation) {
-                        return handleGetterMethodOnCollection(mixeeAdapter, new Object[0], (OneToManyAssociation)mixinMember, memberName);
+                        return handleGetterMethodOnCollection(mixeeAdapter, new Object[0], (OneToManyAssociation)mixinMember, memberId);
                     }
                 } else {
                     throw _Exceptions.illegalState(String.format(
@@ -391,7 +391,7 @@ extends DelegatingInvocationHandlerDefault<T> {
             final ManagedObject targetAdapter,
             final Object[] args,
             final OneToManyAssociation collection,
-            final String memberName) {
+            final String memberId) {
 
         zeroArgsElseThrow(args, "get");
 
@@ -411,12 +411,12 @@ extends DelegatingInvocationHandlerDefault<T> {
             val collectionAccessEvent = new CollectionAccessEvent(getDelegate(), collection.getFeatureIdentifier());
 
             if (currentReferencedObj instanceof Collection) {
-                val collectionViewObject = lookupWrappingObject(memberName,
+                val collectionViewObject = lookupWrappingObject(
                         (Collection<?>) currentReferencedObj, collection);
                 notifyListeners(collectionAccessEvent);
                 return collectionViewObject;
             } else if (currentReferencedObj instanceof Map) {
-                val mapViewObject = lookupWrappingObject(memberName, (Map<?, ?>) currentReferencedObj,
+                val mapViewObject = lookupWrappingObject((Map<?, ?>) currentReferencedObj,
                         collection);
                 notifyListeners(collectionAccessEvent);
                 return mapViewObject;
@@ -430,7 +430,6 @@ extends DelegatingInvocationHandlerDefault<T> {
     }
 
     private Collection<?> lookupWrappingObject(
-            final String memberName,
             final Collection<?> collectionToLookup,
             final OneToManyAssociation otma) {
         if (collectionToLookup instanceof WrappingObject) {
@@ -439,11 +438,10 @@ extends DelegatingInvocationHandlerDefault<T> {
         if(proxyContextHandler == null) {
             throw new IllegalStateException("Unable to create proxy for collection; proxyContextHandler not provided");
         }
-        return proxyContextHandler.proxy(collectionToLookup, memberName, this, otma);
+        return proxyContextHandler.proxy(collectionToLookup, this, otma);
     }
 
     private Map<?, ?> lookupWrappingObject(
-            final String memberName,
             final Map<?, ?> mapToLookup,
             final OneToManyAssociation otma) {
         if (mapToLookup instanceof WrappingObject) {
@@ -452,7 +450,7 @@ extends DelegatingInvocationHandlerDefault<T> {
         if(proxyContextHandler == null) {
             throw new IllegalStateException("Unable to create proxy for collection; proxyContextHandler not provided");
         }
-        return proxyContextHandler.proxy(mapToLookup, memberName, this, otma);
+        return proxyContextHandler.proxy(mapToLookup, this, otma);
     }
 
 
@@ -583,7 +581,7 @@ extends DelegatingInvocationHandlerDefault<T> {
         return !getSyncControl().getExecutionModes().contains(ExecutionMode.SKIP_EXECUTION);
     }
 
-    private void runValidationTask(Runnable task) {
+    private void runValidationTask(final Runnable task) {
         if(!shouldEnforceRules()) {
             return;
         }
@@ -594,7 +592,7 @@ extends DelegatingInvocationHandlerDefault<T> {
         }
     }
 
-    private <X> X runExecutionTask(Supplier<X> task) {
+    private <X> X runExecutionTask(final Supplier<X> task) {
         if(!shouldExecute()) {
             return null;
         }
@@ -606,7 +604,7 @@ extends DelegatingInvocationHandlerDefault<T> {
     }
 
     @SneakyThrows
-    private Object handleException(Exception ex) {
+    private Object handleException(final Exception ex) {
         val exceptionHandler = getSyncControl().getExceptionHandler()
                 .orElse(null);
 
@@ -619,7 +617,7 @@ extends DelegatingInvocationHandlerDefault<T> {
                 : null;
     }
 
-    private Object singleArgUnderlyingElseNull(Object[] args, String name) {
+    private Object singleArgUnderlyingElseNull(final Object[] args, final String name) {
         if (args.length != 1) {
             throw new IllegalArgumentException(String.format(
                     "Invoking '%s' should only have a single argument", name));
@@ -628,7 +626,7 @@ extends DelegatingInvocationHandlerDefault<T> {
         return argumentObj;
     }
 
-    private void zeroArgsElseThrow(Object[] args, String name) {
+    private void zeroArgsElseThrow(final Object[] args, final String name) {
         if (args.length != 0) {
             throw new IllegalArgumentException(String.format(
                     "Invoking '%s' should have no arguments", name));
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/MapInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/MapInvocationHandler.java
index e523558..4438aa4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/MapInvocationHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/MapInvocationHandler.java
@@ -24,10 +24,15 @@ import java.util.Map;
 import org.apache.isis.core.metamodel.commons.ObjectExtensions;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 
-class MapInvocationHandler<T, C> extends AbstractCollectionInvocationHandler<T, C> {
+class MapInvocationHandler<T, C>
+extends AbstractCollectionInvocationHandler<T, C> {
 
-    public MapInvocationHandler(final C collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionToProxy, collectionName, handler, otma);
+    public MapInvocationHandler(
+            final C collectionToProxy,
+            final DomainObjectInvocationHandler<T> handler,
+            final OneToManyAssociation otma) {
+
+        super(collectionToProxy, handler, otma);
 
         try {
             intercept(ObjectExtensions.getMethod(collectionToProxy, "containsKey", Object.class));
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/ProxyContextHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/ProxyContextHandler.java
index 6f48553..cbe2b06 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/ProxyContextHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/ProxyContextHandler.java
@@ -37,9 +37,9 @@ public class ProxyContextHandler {
     @NonNull private final ProxyCreator proxyCreator;
 
     public <T> T proxy(
-            T domainObject,
-            ManagedObject adapter,
-            SyncControl syncControl) {
+            final T domainObject,
+            final ManagedObject adapter,
+            final SyncControl syncControl) {
 
         val invocationHandler = new DomainObjectInvocationHandler<T>(
                 domainObject,
@@ -52,10 +52,10 @@ public class ProxyContextHandler {
     }
 
     public <T> T mixinProxy(
-            T mixin,
-            ManagedObject mixeeAdapter,
-            ManagedObject mixinAdapter,
-            SyncControl syncControl) {
+            final T mixin,
+            final ManagedObject mixeeAdapter,
+            final ManagedObject mixinAdapter,
+            final SyncControl syncControl) {
 
         val invocationHandler = new DomainObjectInvocationHandler<T>(
                 mixin,
@@ -74,12 +74,11 @@ public class ProxyContextHandler {
      */
     public <T, E> Collection<E> proxy(
             final Collection<E> collectionToProxy,
-            final String collectionName,
             final DomainObjectInvocationHandler<T> handler,
             final OneToManyAssociation otma) {
 
         val collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(
-                        collectionToProxy, collectionName, handler, otma);
+                        collectionToProxy, handler, otma);
         collectionInvocationHandler.setResolveObjectChangedEnabled(
                 handler.isResolveObjectChangedEnabled());
 
@@ -92,12 +91,11 @@ public class ProxyContextHandler {
      */
     public <T, P, Q> Map<P, Q> proxy(
             final Map<P, Q> collectionToProxy,
-            final String collectionName,
             final DomainObjectInvocationHandler<T> handler,
             final OneToManyAssociation otma) {
 
         val mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(
-                collectionToProxy, collectionName, handler, otma);
+                collectionToProxy, handler, otma);
         mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
 
         return proxyCreator.instantiateProxy(mapInvocationHandler);
diff --git a/extensions/vw/exceldownload/ui/src/main/java/org/apache/isis/extensions/viewer/wicket/exceldownload/ui/components/ExcelFileModel.java b/extensions/vw/exceldownload/ui/src/main/java/org/apache/isis/extensions/viewer/wicket/exceldownload/ui/components/ExcelFileModel.java
index 63a7598..1a5fd18 100644
--- a/extensions/vw/exceldownload/ui/src/main/java/org/apache/isis/extensions/viewer/wicket/exceldownload/ui/components/ExcelFileModel.java
+++ b/extensions/vw/exceldownload/ui/src/main/java/org/apache/isis/extensions/viewer/wicket/exceldownload/ui/components/ExcelFileModel.java
@@ -55,7 +55,7 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
 
     private final EntityCollectionModel model;
 
-    public ExcelFileModel(EntityCollectionModel model) {
+    public ExcelFileModel(final EntityCollectionModel model) {
         this.model = model;
     }
 
@@ -63,7 +63,7 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
         private final Sheet sheet;
         private int rowNum;
 
-        RowFactory(Sheet sheet) {
+        RowFactory(final Sheet sheet) {
             this.sheet = sheet;
         }
 
@@ -111,7 +111,7 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
                 int i=0;
                 for (ObjectAssociation property : columnProperties) {
                     final Cell cell = row.createCell((short) i++);
-                    cell.setCellValue(property.getName());
+                    cell.setCellValue(property.getFriendlyName(model::getParentObject));
                 }
 
                 final CellStyle dateCellStyle = createDateFormatCellStyle(wb);
@@ -137,7 +137,7 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
         }
     }
 
-    protected void autoSize(final Sheet sh, int numProps) {
+    protected void autoSize(final Sheet sh, final int numProps) {
         for(int prop=0; prop<numProps; prop++) {
             sh.autoSizeColumn(prop);
         }
@@ -155,7 +155,7 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
             final ManagedObject objectAdapter,
             final ObjectAssociation property,
             final Cell cell,
-            CellStyle dateCellStyle) {
+            final CellStyle dateCellStyle) {
 
         val valueAdapter = property.get(objectAdapter);
         val valueAsObj = valueAdapter!=null ? valueAdapter.getPojo() : null;
@@ -201,12 +201,12 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
         // number
         if(valueAsObj instanceof Double) {
             Double value = (Double) valueAsObj;
-            setCellValueForDouble(cell, (double)value);
+            setCellValueForDouble(cell, value);
             return;
         }
         if(valueAsObj instanceof Float) {
             Float value = (Float) valueAsObj;
-            setCellValueForDouble(cell, (double)value);
+            setCellValueForDouble(cell, value);
             return;
         }
         if(valueAsObj instanceof BigDecimal) {
@@ -221,22 +221,22 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
         }
         if(valueAsObj instanceof Long) {
             Long value = (Long) valueAsObj;
-            setCellValueForDouble(cell, (double)value);
+            setCellValueForDouble(cell, value);
             return;
         }
         if(valueAsObj instanceof Integer) {
             Integer value = (Integer) valueAsObj;
-            setCellValueForDouble(cell, (double)value);
+            setCellValueForDouble(cell, value);
             return;
         }
         if(valueAsObj instanceof Short) {
             Short value = (Short) valueAsObj;
-            setCellValueForDouble(cell, (double)value);
+            setCellValueForDouble(cell, value);
             return;
         }
         if(valueAsObj instanceof Byte) {
             Byte value = (Byte) valueAsObj;
-            setCellValueForDouble(cell, (double)value);
+            setCellValueForDouble(cell, value);
             return;
         }
 
@@ -245,11 +245,11 @@ class ExcelFileModel extends LoadableDetachableModel<File> {
         return;
     }
 
-    private static void setCellValueForDouble(final Cell cell, double value2) {
+    private static void setCellValueForDouble(final Cell cell, final double value2) {
         cell.setCellValue(value2);
     }
 
-    private static void setCellValueForDate(final Cell cell, Date date, CellStyle dateCellStyle) {
+    private static void setCellValueForDate(final Cell cell, final Date date, final CellStyle dateCellStyle) {
         cell.setCellValue(date);
         cell.setCellStyle(dateCellStyle);
     }
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/collections/TableViewFx.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/collections/TableViewFx.java
index 2c39aee..5414c4c 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/collections/TableViewFx.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/collections/TableViewFx.java
@@ -101,7 +101,7 @@ public class TableViewFx extends VBox {
                 : new TableViewFx(uiContext, elementSpec, elements, where);
     }
 
-    private Can<OneToOneAssociation> columnProperties(ObjectSpecification elementSpec, Where where) {
+    private Can<OneToOneAssociation> columnProperties(final ObjectSpecification elementSpec, final Where where) {
 
         //TODO honor column order (as per layout)
         return elementSpec.streamProperties(MixedIn.INCLUDED)
@@ -163,7 +163,7 @@ public class TableViewFx extends VBox {
 
         // property columns
         columnProperties.forEach(property->{
-            val column = _fx.newColumn(objectGrid, property.getName(), String.class);
+            val column = _fx.newColumn(objectGrid, property.getColumnName(), String.class);
             column.setCellValueFactory(cellDataFeatures -> {
                 log.debug("about to get property value for property {}", property.getId());
                 val targetObject = cellDataFeatures.getValue();
@@ -188,8 +188,8 @@ public class TableViewFx extends VBox {
     }
 
     private String stringifyPropertyValue(
-            ObjectAssociation property,
-            ManagedObject targetObject) {
+            final ObjectAssociation property,
+            final ManagedObject targetObject) {
 
         try {
             val propertyValue = property.get(targetObject);
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableViewVaa.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableViewVaa.java
index e067e8f..d19a1eb 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableViewVaa.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableViewVaa.java
@@ -95,7 +95,7 @@ public class TableViewVaa extends VerticalLayout {
                 : new TableViewVaa(elementSpec, elements, where);
     }
 
-    private Can<OneToOneAssociation> columnProperties(ObjectSpecification elementSpec, Where where) {
+    private Can<OneToOneAssociation> columnProperties(final ObjectSpecification elementSpec, final Where where) {
 
         //TODO honor column order (as per layout)
         return elementSpec.streamProperties(MixedIn.INCLUDED)
@@ -161,7 +161,7 @@ public class TableViewVaa extends VerticalLayout {
                 log.debug("about to get property value for property {}", property.getId());
                 return stringifyPropertyValue(property, targetObject);
             })
-            .setHeader(property.getName());
+            .setHeader(property.getColumnName());
         });
 
         // populate the model
@@ -172,8 +172,8 @@ public class TableViewVaa extends VerticalLayout {
     }
 
     private String stringifyPropertyValue(
-            ObjectAssociation property,
-            ManagedObject targetObject) {
+            final ObjectAssociation property,
+            final ManagedObject targetObject) {
         try {
             val propertyValue = property.get(targetObject);
             return propertyValue == null
diff --git a/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java b/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
index b0322f5..9061d6a 100644
--- a/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
+++ b/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
@@ -143,8 +143,8 @@ class DomainModelTest_usingGoodDomain {
         val mx_action = holderSpec.getActionElseFail("action"); // when @Action at type level
         assertNotNull(mx_action);
         assertEquals("action", mx_action.getId());
-        assertEquals("foo", mx_action.getName());
-        assertEquals("bar", mx_action.getDescription());
+        assertEquals("foo", mx_action.getStaticFriendlyName().get());
+        assertEquals("bar", mx_action.getStaticDescription().get());
         assertHasPublishedActionFacet(mx_action);
 
         val mx_action2 = holderSpec.getActionElseFail("action2"); // proper mixed-in action support
@@ -154,26 +154,26 @@ class DomainModelTest_usingGoodDomain {
         val mx_property = holderSpec.getAssociationElseFail("property"); // when @Property at type level
         assertNotNull(mx_property);
         assertEquals("property", mx_property.getId());
-        assertEquals("foo", mx_property.getName());
-        assertEquals("bar", mx_property.getDescription());
+        assertEquals("foo", mx_property.getStaticFriendlyName().get());
+        assertEquals("bar", mx_property.getStaticDescription().get());
 
         val mx_property2 = holderSpec.getAssociationElseFail("property2"); // when @Property at method level
         assertNotNull(mx_property2);
         assertEquals("property2", mx_property2.getId());
-        assertEquals("foo", mx_property2.getName());
-        assertEquals("bar", mx_property2.getDescription());
+        assertEquals("foo", mx_property2.getStaticFriendlyName().get());
+        assertEquals("bar", mx_property2.getStaticDescription().get());
 
         val mx_collection = holderSpec.getAssociationElseFail("collection"); // when @Collection at type level
         assertNotNull(mx_collection);
         assertEquals("collection", mx_collection.getId());
-        assertEquals("foo", mx_collection.getName());
-        assertEquals("bar", mx_collection.getDescription());
+        assertEquals("foo", mx_collection.getStaticFriendlyName().get());
+        assertEquals("bar", mx_collection.getStaticDescription().get());
 
         val mx_collection2 = holderSpec.getAssociationElseFail("collection2"); // when @Collection at method level
         assertNotNull(mx_collection2);
         assertEquals("collection2", mx_collection2.getId());
-        assertEquals("foo", mx_collection2.getName());
-        assertEquals("bar", mx_collection2.getDescription());
+        assertEquals("foo", mx_collection2.getStaticFriendlyName().get());
+        assertEquals("bar", mx_collection2.getStaticDescription().get());
 
     }
 
@@ -191,7 +191,7 @@ class DomainModelTest_usingGoodDomain {
 
     @ParameterizedTest
     @MethodSource("provideProperMemberInheritanceTypes")
-    void titleAndIconName_shouldBeInheritable(Class<?> type) {
+    void titleAndIconName_shouldBeInheritable(final Class<?> type) {
 
         val spec = specificationLoader.specForTypeElseFail(type);
 
@@ -208,33 +208,33 @@ class DomainModelTest_usingGoodDomain {
 
     @ParameterizedTest
     @MethodSource("provideProperMemberInheritanceTypes")
-    void metamodelContributingMembers_shouldBeInheritable(Class<?> type) {
+    void metamodelContributingMembers_shouldBeInheritable(final Class<?> type) {
 
         val holderSpec = specificationLoader.specForTypeElseFail(type);
 
         val action = holderSpec.getActionElseFail("sampleAction");
         assertNotNull(action);
         assertEquals("sampleAction", action.getId());
-        assertEquals("foo", action.getName());
-        assertEquals("bar", action.getDescription());
+        assertEquals("foo", action.getStaticFriendlyName().get());
+        assertEquals("bar", action.getStaticDescription().get());
 
         val property = holderSpec.getAssociationElseFail("sampleProperty");
         assertNotNull(property);
         assertEquals("sampleProperty", property.getId());
-        assertEquals("foo", property.getName());
-        assertEquals("bar", property.getDescription());
+        assertEquals("foo", property.getStaticFriendlyName().get());
+        assertEquals("bar", property.getStaticDescription().get());
 
         val collection = holderSpec.getAssociationElseFail("sampleCollection");
         assertNotNull(collection);
         assertEquals("sampleCollection", collection.getId());
-        assertEquals("foo", collection.getName());
-        assertEquals("bar", collection.getDescription());
+        assertEquals("foo", collection.getStaticFriendlyName().get());
+        assertEquals("bar", collection.getStaticDescription().get());
 
     }
 
     @ParameterizedTest
     @MethodSource("provideProperMemberInheritanceTypes")
-    void metamodelContributingActions_shouldBeUnique_whenOverridden(Class<?> type) {
+    void metamodelContributingActions_shouldBeUnique_whenOverridden(final Class<?> type) {
 
         if(type.isInterface()
                 && type.getSuperclass()==null) {
@@ -246,8 +246,8 @@ class DomainModelTest_usingGoodDomain {
         val super_action = holderSpec.getActionElseFail("sampleActionOverride");
         assertNotNull(super_action);
         assertEquals("sampleActionOverride", super_action.getId());
-        assertEquals("foo", super_action.getName());
-        assertEquals("bar", super_action.getDescription());
+        assertEquals("foo", super_action.getStaticFriendlyName().get());
+        assertEquals("bar", super_action.getStaticDescription().get());
 
         assertEquals(1L, holderSpec.streamAnyActions(MixedIn.EXCLUDED)
                 .filter(prop->prop.getId().equals("sampleActionOverride"))
@@ -257,7 +257,7 @@ class DomainModelTest_usingGoodDomain {
 
     @ParameterizedTest
     @MethodSource("provideProperMemberInheritanceTypes")
-    void metamodelContributingProperties_shouldBeUnique_whenOverridden(Class<?> type) {
+    void metamodelContributingProperties_shouldBeUnique_whenOverridden(final Class<?> type) {
 
         if(type.isInterface()
                 && type.getSuperclass()==null) {
@@ -269,8 +269,8 @@ class DomainModelTest_usingGoodDomain {
         val super_property = holderSpec.getAssociationElseFail("samplePropertyOverride");
         assertNotNull(super_property);
         assertEquals("samplePropertyOverride", super_property.getId());
-        assertEquals("foo", super_property.getName());
-        assertEquals("bar", super_property.getDescription());
+        assertEquals("foo", super_property.getStaticFriendlyName().get());
+        assertEquals("bar", super_property.getStaticDescription().get());
 
         assertEquals(1L, holderSpec.streamProperties(MixedIn.EXCLUDED)
                 .filter(prop->prop.getId().equals("samplePropertyOverride"))
@@ -386,15 +386,15 @@ class DomainModelTest_usingGoodDomain {
 
     // -- HELPER
 
-    private void assertHasProperty(ObjectSpecification spec, String propertyId) {
+    private void assertHasProperty(final ObjectSpecification spec, final String propertyId) {
         spec.getPropertyElseFail(propertyId);
     }
 
-    private void assertHasAction(ObjectSpecification spec, String actionId) {
+    private void assertHasAction(final ObjectSpecification spec, final String actionId) {
         spec.getActionElseFail(actionId);
     }
 
-    private void assertHasPublishedActionFacet(FacetHolder facetHolder) {
+    private void assertHasPublishedActionFacet(final FacetHolder facetHolder) {
         val facet = facetHolder.getFacet(ExecutionPublishingFacet.class);
         assertNotNull(facet);
     }
diff --git a/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/ExcelConverter.java b/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/ExcelConverter.java
index da4e19c..8559dc8 100644
--- a/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/ExcelConverter.java
+++ b/subdomains/excel/applib/src/main/java/org/apache/isis/subdomains/excel/applib/dom/util/ExcelConverter.java
@@ -119,7 +119,7 @@ class ExcelConverter {
 
     // //////////////////////////////////////
 
-    File appendSheet(final List<WorksheetContent> worksheetContents, XSSFWorkbook workbook) throws IOException {
+    File appendSheet(final List<WorksheetContent> worksheetContents, final XSSFWorkbook workbook) throws IOException {
         final Set<String> worksheetNames = worksheetContents.stream()
                 .map(x -> x.getSpec().getSheetName())
                 .collect(Collectors.toSet());
@@ -157,10 +157,10 @@ class ExcelConverter {
                 .map(objectManager::adapt)
                 .collect(Collectors.toList());
 
-        final List<ObjectAssociation> propertyList = _Lists.newArrayList();
+        final List<OneToOneAssociation> propertyList = _Lists.newArrayList();
 
         specificationLoader.specForType(factory.getCls())
-        .ifPresent(spec->spec.streamAssociations(MixedIn.INCLUDED)
+        .ifPresent(spec->spec.streamProperties(MixedIn.INCLUDED)
                 .filter(VISIBLE_PROPERTIES)
                 .forEach(propertyList::add));
 
@@ -179,9 +179,9 @@ class ExcelConverter {
 
         // header row
         int i = 0;
-        for (final ObjectAssociation property : propertyList) {
+        for (val property : propertyList) {
             final Cell cell = headerRow.createCell(i++);
-            cell.setCellValue(property.getName());
+            cell.setCellValue(property.getColumnName());
         }
 
         final CellMarshaller cellMarshaller = newCellMarshaller(workbook);
@@ -190,13 +190,12 @@ class ExcelConverter {
         for (final ManagedObject objectAdapter : adapters) {
             final Row detailRow = rowFactory.newRow();
             i = 0;
-            for (final ObjectAssociation oa : propertyList) {
+            for (val property : propertyList) {
                 final Cell cell = detailRow.createCell(i++);
-                final OneToOneAssociation otoa = (OneToOneAssociation) oa;
-                if (annotatedAsHyperlink.contains(oa)){
-                    cellMarshaller.setCellValueForHyperlink(objectAdapter, otoa, cell);
+                if (annotatedAsHyperlink.contains(property)){
+                    cellMarshaller.setCellValueForHyperlink(objectAdapter, property, cell);
                 } else {
-                    cellMarshaller.setCellValue(objectAdapter, otoa, cell);
+                    cellMarshaller.setCellValue(objectAdapter, property, cell);
                 }
             }
         }
@@ -296,7 +295,7 @@ class ExcelConverter {
         pivotSourceSheet.shiftRows(3, pivotSourceSheet.getLastRowNum(), -3);
     }
 
-    private void validateAnnotations(final List<? extends ObjectAssociation> list, Class<?> cls) throws IllegalArgumentException{
+    private void validateAnnotations(final List<? extends ObjectAssociation> list, final Class<?> cls) throws IllegalArgumentException{
 
         if (fieldsAnnotatedWith(cls, PivotRow.class).size()==0){
             throw new IllegalArgumentException("No annotation for row found");
@@ -557,7 +556,7 @@ class ExcelConverter {
         }
 
         return objectSpec.streamProperties(MixedIn.INCLUDED)
-        .filter(association -> propertyNameOrId.equalsIgnoreCase(association.getName())
+        .filter(association -> propertyNameOrId.equalsIgnoreCase(association.getColumnName())
                             || propertyNameOrId.equalsIgnoreCase(association.getId()))
         .findFirst()
         .orElse(null);
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java
index a05db72..9057c33 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java
@@ -30,7 +30,6 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.facets.all.described.MemberDescribedFacet;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -85,8 +84,8 @@ public final class ActionUiMetaModel implements Serializable {
             final ObjectAction objectAction) {
 
         this(   objectAction.getMemento(),
-                objectAction.getName(),
-                getDescription(actionHolder, objectAction).orElse(ObjectAction.Util.descriptionOf(objectAction)),
+                objectAction.getFriendlyName(actionHolder.asProvider()),
+                objectAction.getDescription(actionHolder.asProvider()),
                 ObjectAction.Util.returnsBlobOrClob(objectAction),
                 objectAction.isPrototype(),
                 ObjectAction.Util.actionIdentifierFor(objectAction),
@@ -144,18 +143,5 @@ public final class ActionUiMetaModel implements Serializable {
         return DisablingUiModel.of(!enabled, usability.getReason()) ;
     }
 
-    // -- DESCRIBED AS
-
-    private static Optional<String> getDescription(
-            @NonNull final ManagedObject actionHolder,
-            @NonNull final ObjectAction objectAction) {
-
-        return objectAction.lookupFacet(MemberDescribedFacet.class)
-        .map(MemberDescribedFacet::getSpecialization)
-        .map(specialization->specialization
-                .fold(textFacet->textFacet.translated(),
-                      textFacet->textFacet.textElseNull(actionHolder)));
-
-    }
 
 }
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 97f6969..d8003cc 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
@@ -87,6 +87,15 @@ public interface FormUiModel extends HasTitle {
 
     }
 
+    // -- NAME
+
+    /**
+     * Action's friendly (translated) name.
+     */
+    default String getFriendlyName() {
+        return getMetaModel().getFriendlyName(this::getOwner);
+    }
+
     // -- HAS TITLE
 
     @Override
@@ -106,7 +115,10 @@ public interface FormUiModel extends HasTitle {
             }
             buf.append(ManagedObjects.abbreviatedTitleOf(paramValue, 8, "..."));
         });
-        return target.titleString() + "." + objectAction.getName() + (buf.length()>0?"(" + buf.toString() + ")":"");
+        return target.titleString() + "." + getFriendlyName()
+            + (buf.length()>0
+                    ?"(" + buf.toString() + ")"
+                    :"");
     }
 
     // -- 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 f046cca..807d126 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
@@ -37,8 +37,8 @@ public interface ScalarUiModel {
     ManagedObject getOwner();
 
     /** feature name */
-    default String getName() {
-        return getMetaModel().getName();
+    default String getFriendlyName() {
+        return getMetaModel().getFriendlyName(this::getOwner);
     }
 
     default boolean isCollection() {
@@ -47,7 +47,7 @@ public interface ScalarUiModel {
     }
 
     default String getDescribedAs() {
-        return getMetaModel().getDescription();
+        return getMetaModel().getDescription(this::getOwner);
     }
 
     /**
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/IResourceContext.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/IResourceContext.java
index d25f160..7c3ad72 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/IResourceContext.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/IResourceContext.java
@@ -30,7 +30,6 @@ import org.apache.isis.applib.services.iactn.InteractionProvider;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAdapterLinkTo;
 import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
@@ -99,7 +98,7 @@ public interface IResourceContext {
 
     // -- UTILITY
 
-    default Optional<ManagedObject> getObjectAdapterForOidFromHref(String oidFromHref) {
+    default Optional<ManagedObject> getObjectAdapterForOidFromHref(final String oidFromHref) {
         String oidStrUnencoded = UrlDecoderUtils.urlDecode(oidFromHref);
         return Bookmark.parse(oidStrUnencoded)
         .flatMap(getMetaModelContext()::loadObject);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererFactory.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererFactory.java
index b60cb2c..a9d37eb 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererFactory.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererFactory.java
@@ -25,7 +25,7 @@ public interface RendererFactory {
 
     RepresentationType getRepresentationType();
 
-    ReprRenderer<?, ?> newRenderer(
+    ReprRenderer<?> newRenderer(
             IResourceContext resourceContext,
             LinkFollowSpecs linkFollower,
             JsonRepresentation representation);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java
index b1685ad..8103cba 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java
@@ -22,12 +22,12 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
-public interface ReprRenderer<R extends ReprRenderer<R, T>, T> {
+public interface ReprRenderer<T> {
 
     MediaType getMediaType();
 
-    R with(T t);
+    ReprRenderer<T> with(T t);
 
-    public JsonRepresentation render();
+    JsonRepresentation render();
 
 }
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
index 388aab9..e22ee9b 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
@@ -24,6 +24,7 @@ import java.util.stream.Stream;
 
 import javax.ws.rs.core.MediaType;
 
+import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -39,8 +40,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.DomainTypeRep
 import lombok.Getter;
 import lombok.val;
 
-public abstract class ReprRendererAbstract<R extends ReprRendererAbstract<R, T>, T>
-implements ReprRenderer<R, T> {
+public abstract class ReprRendererAbstract<T>
+implements ReprRenderer<T> {
 
     @Getter protected final IResourceContext resourceContext;
     @Getter protected final JsonValueEncoder jsonValueEncoder;
@@ -95,24 +96,23 @@ implements ReprRenderer<R, T> {
         return representationType.getJsonMediaType(mediaTypeParams);
     }
 
-    protected void addMediaTypeParams(String param, String paramValue) {
+    protected void addMediaTypeParams(final String param, final String paramValue) {
         mediaTypeParams.put(param, paramValue);
     }
 
-    @SuppressWarnings("unchecked")
-    public R includesSelf() {
+    public <R extends ReprRendererAbstract<T>> R includesSelf() {
         this.includesSelf = true;
-        return (R) this;
+        return _Casts.uncheckedCast(this);
     }
 
-    public R withLink(final Rel rel, final String href) {
+    public <R extends ReprRendererAbstract<T>> R withLink(final Rel rel, final String href) {
         if (href != null) {
             getLinks().arrayAdd(LinkBuilder.newBuilder(resourceContext, rel.getName(), representationType, href).build());
         }
-        return cast(this);
+        return _Casts.uncheckedCast(this);
     }
 
-    public R withLink(final Rel rel, final JsonRepresentation link) {
+    public <R extends ReprRendererAbstract<T>> R withLink(final Rel rel, final JsonRepresentation link) {
         final String relStr = link.getString("rel");
         if (relStr == null || !relStr.equals(rel.getName())) {
             throw new IllegalArgumentException("Provided link does not have a 'rel' of '" + rel.getName() + "'; was: " + link);
@@ -120,7 +120,7 @@ implements ReprRenderer<R, T> {
         if (link != null) {
             getLinks().arrayAdd(link);
         }
-        return cast(this);
+        return _Casts.uncheckedCast(this);
     }
 
 
@@ -165,18 +165,14 @@ implements ReprRenderer<R, T> {
         return extensions;
     }
 
-    public R withExtensions(final JsonRepresentation extensions) {
+    public ReprRendererAbstract<T> withExtensions(final JsonRepresentation extensions) {
         if (!extensions.isMap()) {
             throw new IllegalArgumentException("extensions must be a map");
         }
         representation.mapPut("extensions", extensions);
-        return cast(this);
+        return this;
     }
 
-    @SuppressWarnings("unchecked")
-    protected static <R extends ReprRendererAbstract<R, T>, T> R cast(final ReprRendererAbstract<R, T> builder) {
-        return (R) builder;
-    }
 
     @Override
     public abstract JsonRepresentation render();
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
index ded48b9..7ffced6 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
@@ -51,7 +51,7 @@ public final class Responses {
     }
 
     public static Response.ResponseBuilder ofOk(
-            final ReprRenderer<?, ?> renderer,
+            final ReprRenderer<?> renderer,
             final Caching caching) {
         return ofOk(renderer, caching, null);
     }
@@ -60,7 +60,7 @@ public final class Responses {
      * @param rootRepresentationIfAny - if specified, is used for entity; otherwise the renderer is used.  The idea is that the renderer will be set up to render to some sub-node of root representation
      */
     public static Response.ResponseBuilder ofOk(
-            final ReprRenderer<?, ?> renderer,
+            final ReprRenderer<?> renderer,
             final Caching caching,
             final JsonRepresentation rootRepresentationIfAny) {
 
@@ -86,9 +86,9 @@ public final class Responses {
         return response;
     }
 
-    private static Date now(final ReprRenderer<?, ?> renderer) {
+    private static Date now(final ReprRenderer<?> renderer) {
         if(renderer instanceof ReprRendererAbstract) {
-            ((ReprRendererAbstract<?, ?>)renderer).getResourceContext().getMetaModelContext().getServiceRegistry()
+            ((ReprRendererAbstract<?>)renderer).getResourceContext().getMetaModelContext().getServiceRegistry()
             .lookupServiceElseFail(ClockService.class).getClock().javaUtilDate();
         }
         return new Date();
@@ -105,14 +105,14 @@ public final class Responses {
         return responseBuilder;
     }
 
-    public static JsonMapper.PrettyPrinting inferPrettyPrinting(final ReprRenderer<?, ?> renderer) {
+    public static JsonMapper.PrettyPrinting inferPrettyPrinting(final ReprRenderer<?> renderer) {
 
         if(renderer instanceof ReprRendererAbstract) {
-            val systemEnvironment =  ((ReprRendererAbstract<?, ?>) renderer).getResourceContext()
+            val systemEnvironment =  ((ReprRendererAbstract<?>) renderer).getResourceContext()
                     .getMetaModelContext().getSystemEnvironment();
             return systemEnvironment.isPrototyping()
                     ? JsonMapper.PrettyPrinting.ENABLE
-                            : JsonMapper.PrettyPrinting.DISABLE;
+                    : JsonMapper.PrettyPrinting.DISABLE;
         }
 
         return JsonMapper.PrettyPrinting.DISABLE;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
index 46401ed..2d24b48 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
@@ -39,10 +39,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
 import lombok.NonNull;
 
-public abstract class AbstractObjectMemberReprRenderer<
-    R extends ReprRendererAbstract<R, ManagedMember>,
-    T extends ObjectMember>
-extends ReprRendererAbstract<R, ManagedMember> {
+public abstract class AbstractObjectMemberReprRenderer<T extends ObjectMember>
+extends ReprRendererAbstract<ManagedMember> {
 
     protected enum Mode {
         INLINE, FOLLOWED, STANDALONE, MUTATED, ARGUMENTS, EVENT_SERIALIZATION;
@@ -109,45 +107,45 @@ extends ReprRendererAbstract<R, ManagedMember> {
 
 
     @Override
-    public R with(final ManagedMember objectAndMember) {
+    public AbstractObjectMemberReprRenderer<T> with(final ManagedMember objectAndMember) {
         this.objectAdapter = objectAndMember.getOwner();
         this.objectMember = _Casts.uncheckedCast(objectAndMember.getMetaModel());
         this.objectMemberType = MemberType.determineFrom(objectMember);
         this.memberId = objectMember.getId();
         usingLinkTo(new DomainObjectLinkTo());
 
-        return cast(this);
+        return this;
     }
 
     /**
      * Must be called after {@link #with(ManagedMember)} (which provides the
      * {@link #objectAdapter}).
      */
-    public R usingLinkTo(final ObjectAdapterLinkTo linkTo) {
+    public AbstractObjectMemberReprRenderer<T> usingLinkTo(final ObjectAdapterLinkTo linkTo) {
         this.linkTo = linkTo.usingUrlBase(resourceContext).with(objectAdapter);
-        return cast(this);
+        return this;
     }
 
     /**
      * Indicate that this is a standalone representation.
      */
-    public R asStandalone() {
+    public AbstractObjectMemberReprRenderer<T> asStandalone() {
         mode = Mode.STANDALONE;
-        return cast(this);
+        return this;
     }
 
-    public R asEventSerialization() {
+    public AbstractObjectMemberReprRenderer<T> asEventSerialization() {
         mode = Mode.EVENT_SERIALIZATION;
-        return cast(this);
+        return this;
     }
 
     /**
      * Indicate that this is a representation to include as the result of a
      * followed link.
      */
-    public R asFollowed() {
+    public AbstractObjectMemberReprRenderer<T> asFollowed() {
         mode = Mode.FOLLOWED;
-        return cast(this);
+        return this;
     }
 
     /**
@@ -157,14 +155,14 @@ extends ReprRendererAbstract<R, ManagedMember> {
      * <p>
      * The effect of this is to suppress the link to self.
      */
-    public R asMutated() {
+    public AbstractObjectMemberReprRenderer<T> asMutated() {
         mode = Mode.MUTATED;
-        return cast(this);
+        return this;
     }
 
-    public R asArguments() {
+    public AbstractObjectMemberReprRenderer<T> asArguments() {
         mode = Mode.ARGUMENTS;
-        return cast(this);
+        return this;
     }
 
     /**
@@ -202,7 +200,7 @@ extends ReprRendererAbstract<R, ManagedMember> {
         }
     }
 
-    public void withMemberMode(ManagedMember.RepresentationMode memberMode) {
+    public void withMemberMode(final ManagedMember.RepresentationMode memberMode) {
         if(memberMode.isWrite()) {
             this.asMutated();
         } else {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
index dc11fe8..e96cea9 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
@@ -37,7 +37,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultReprRenderer, ObjectAndActionInvocation> {
+public class ActionResultReprRenderer
+extends ReprRendererAbstract<ObjectAndActionInvocation> {
 
     private ObjectAdapterLinkTo adapterLinkTo = new DomainObjectLinkTo();
 
@@ -123,13 +124,13 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
 
         // we have a returnedAdapter with a spec, but it might hold no pojo (null)
 
-        final ReprRendererAbstract<?, ?> renderer = buildResultRenderer(resultType, representation);
+        final ReprRendererAbstract<?> renderer = buildResultRenderer(resultType, representation);
         if(renderer != null) {
             renderer.render();
         }
     }
 
-    private ReprRendererAbstract<?, ?> buildResultRenderer(
+    private ReprRendererAbstract<?> buildResultRenderer(
             final ResultType resultType,
             final JsonRepresentation representation) {
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index 232c398..901544c 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -50,7 +50,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.DomainTypeRep
 
 import lombok.val;
 
-public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectReprRenderer, ManagedObject> {
+public class DomainObjectReprRenderer
+extends ReprRendererAbstract<ManagedObject> {
 
     private static final String X_RO_DOMAIN_TYPE = "x-ro-domain-type";
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
index 231843a..3e57342 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
@@ -31,7 +31,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Stream<ManagedObject>> {
+public class ListReprRenderer
+extends ReprRendererAbstract<Stream<ManagedObject>> {
 
     private ObjectAdapterLinkTo linkTo;
     private List<ManagedObject> objectAdapters;
@@ -59,7 +60,7 @@ public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Str
                         return this;
     }
 
-    public ListReprRenderer withElementRel(Rel elementRel) {
+    public ListReprRenderer withElementRel(final Rel elementRel) {
         this.elementRel = elementRel;
         return this;
     }
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberType.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberType.java
index 3e35181..8d9fc6d 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberType.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberType.java
@@ -50,8 +50,7 @@ public enum MemberType {
         }
     },
     /**
-     * {@link #getMutators()} are keyed by
-     * {@link CollectionSemantics#getAddToKey()}
+     * {@link #getMutators()} are empty}
      */
     COLLECTION("collections/", RepresentationType.OBJECT_COLLECTION,
             Collections.emptyMap()
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
index fdffca7..6038272 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
@@ -41,16 +41,17 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.ActionDescrip
 
 import lombok.val;
 
-public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectActionReprRenderer, ObjectAction> {
+public class ObjectActionReprRenderer
+extends AbstractObjectMemberReprRenderer<ObjectAction> {
 
-    public ObjectActionReprRenderer(IResourceContext resourceContext) {
+    public ObjectActionReprRenderer(final IResourceContext resourceContext) {
         this(resourceContext, null, null, JsonRepresentation.newMap());
     }
 
     public ObjectActionReprRenderer(
             final IResourceContext resourceContext,
             final LinkFollowSpecs linkFollowSpecs,
-            String actionId,
+            final String actionId,
             final JsonRepresentation representation) {
         super(resourceContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation,
                 Where.OBJECT_FORMS);
@@ -141,8 +142,8 @@ public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer<O
         final JsonRepresentation paramRep = JsonRepresentation.newMap();
         paramRep.mapPut("num", param.getNumber());
         paramRep.mapPut("id", param.getId());
-        paramRep.mapPut("name", param.getName());
-        paramRep.mapPut("description", param.getDescription());
+        paramRep.mapPut("name", param.getFriendlyName(objectAdapter.asProvider()));
+        paramRep.mapPut("description", param.getDescription(objectAdapter.asProvider()));
         final Object paramChoices = choicesFor(param, interactionInitiatedBy);
         if (paramChoices != null) {
             paramRep.mapPut("choices", paramChoices);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
index fab21a5..770ab8f 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
@@ -40,7 +40,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.CollectionDes
 
 import lombok.val;
 
-public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectCollectionReprRenderer, OneToManyAssociation> {
+public class ObjectCollectionReprRenderer
+extends AbstractObjectMemberReprRenderer<OneToManyAssociation> {
 
     public ObjectCollectionReprRenderer(
             final IResourceContext resourceContext,
@@ -126,7 +127,7 @@ public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRender
         representation.mapPut("value", list);
     }
 
-    private boolean renderEagerly(ManagedObject valueAdapter) {
+    private boolean renderEagerly(final ManagedObject valueAdapter) {
         return renderEagerly() && resourceContext.canEagerlyRender(valueAdapter);
     }
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
index 2725185..eaa2589 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
@@ -44,7 +44,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.PropertyDescr
 import lombok.val;
 
 public class ObjectPropertyReprRenderer
-extends AbstractObjectMemberReprRenderer<ObjectPropertyReprRenderer, OneToOneAssociation> {
+extends AbstractObjectMemberReprRenderer<OneToOneAssociation> {
 
     public ObjectPropertyReprRenderer(final IResourceContext context) {
         this(context, null, null, JsonRepresentation.newMap());
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
index ada27c0..8289f37 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
@@ -30,7 +30,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererException;
 
-public class ScalarValueReprRenderer extends ReprRendererAbstract<ScalarValueReprRenderer, ManagedObject> {
+public class ScalarValueReprRenderer
+extends ReprRendererAbstract<ManagedObject> {
 
     private ObjectSpecification returnType;
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
index 68d0a80..292cd11 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domaintypes;
 
-import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
@@ -27,12 +26,17 @@ import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-public abstract class AbstractTypeFeatureReprRenderer<R extends ReprRendererAbstract<R, ParentSpecAndFeature<T>>, T extends ObjectFeature> extends ReprRendererAbstract<R, ParentSpecAndFeature<T>> {
+public abstract class AbstractTypeFeatureReprRenderer<T extends ObjectFeature>
+extends ReprRendererAbstract<ParentSpecAndFeature<T>> {
 
     protected ObjectSpecification objectSpecification;
     protected T objectFeature;
 
-    public AbstractTypeFeatureReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+    public AbstractTypeFeatureReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final RepresentationType representationType,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, representationType, representation);
     }
 
@@ -45,11 +49,11 @@ public abstract class AbstractTypeFeatureReprRenderer<R extends ReprRendererAbst
     }
 
     @Override
-    public R with(final ParentSpecAndFeature<T> specAndFeature) {
+    public AbstractTypeFeatureReprRenderer<T> with(final ParentSpecAndFeature<T> specAndFeature) {
         objectSpecification = specAndFeature.getParentSpec();
         objectFeature = specAndFeature.getObjectFeature();
 
-        return cast(this);
+        return this;
     }
 
     @Override
@@ -94,15 +98,17 @@ public abstract class AbstractTypeFeatureReprRenderer<R extends ReprRendererAbst
     protected abstract void putExtensionsSpecificToFeature();
 
     protected void putExtensionsName() {
-        final String friendlyName = getObjectFeature().getName();
-        getExtensions().mapPut("friendlyName", friendlyName);
+        getExtensions()
+        .mapPut("friendlyName",
+                getObjectFeature().getStaticFriendlyName()
+                .orElse("!imperative"));
     }
 
     protected void putExtensionsDescriptionIfAvailable() {
-        final String description = getObjectFeature().getDescription();
-        if (!_Strings.isNullOrEmpty(description)) {
-            getExtensions().mapPut("description", description);
-        }
+        getExtensions()
+        .mapPut("description",
+                getObjectFeature().getStaticDescription()
+                .orElse("!imperative"));
     }
 
 }
\ No newline at end of file
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
index 8c76a7a..afc8adc 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
@@ -25,14 +25,18 @@ import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
-import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.MemberType;
 
-public abstract class AbstractTypeMemberReprRenderer<R extends ReprRendererAbstract<R, ParentSpecAndFeature<T>>, T extends ObjectMember> extends AbstractTypeFeatureReprRenderer<R, T> {
+public abstract class AbstractTypeMemberReprRenderer<T extends ObjectMember>
+extends AbstractTypeFeatureReprRenderer<T> {
 
     protected MemberType memberType;
 
-    public AbstractTypeMemberReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+    public AbstractTypeMemberReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final RepresentationType representationType,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, representationType, representation);
     }
 
@@ -44,7 +48,7 @@ public abstract class AbstractTypeMemberReprRenderer<R extends ReprRendererAbstr
     }
 
     @Override
-    public R with(final ParentSpecAndFeature<T> specAndFeature) {
+    public AbstractTypeMemberReprRenderer<T> with(final ParentSpecAndFeature<T> specAndFeature) {
         super.with(specAndFeature);
         memberType = MemberType.determineFrom(objectFeature);
 
@@ -52,7 +56,7 @@ public abstract class AbstractTypeMemberReprRenderer<R extends ReprRendererAbstr
         representation.mapPut("id", objectFeature.getId());
         representation.mapPut("memberType", memberType.getName());
 
-        return cast(this);
+        return this;
     }
 
     @Override
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
index 8c17c19..65f55ca 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
@@ -31,16 +31,24 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 
 import lombok.val;
 
-public class ActionDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<ActionDescriptionReprRenderer, ObjectAction> {
+public class ActionDescriptionReprRenderer
+extends AbstractTypeMemberReprRenderer<ObjectAction> {
 
-    public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final ObjectAction objectAction) {
+    public static LinkBuilder newLinkToBuilder(
+            final IResourceContext resourceContext,
+            final Rel rel,
+            final ObjectSpecification objectSpecification,
+            final ObjectAction objectAction) {
         final String domainType = objectSpecification.getLogicalTypeName();
         final String actionId = objectAction.getId();
         final String url = "domain-types/" + domainType + "/actions/" + actionId;
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.ACTION_DESCRIPTION, url);
     }
 
-    public ActionDescriptionReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public ActionDescriptionReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.ACTION_DESCRIPTION, representation);
     }
 
@@ -51,40 +59,47 @@ public class ActionDescriptionReprRenderer extends AbstractTypeMemberReprRendere
         addLinkToElementTypeIfAny();
     }
 
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
+    }
+
+    // -- HELPER
+
     private void addParameters() {
         final JsonRepresentation parameterList = JsonRepresentation.newArray();
         val parameters = getObjectFeature().getParameters();
         for (final ObjectActionParameter parameter : parameters) {
-            final LinkBuilder linkBuilder = ActionParameterDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ACTION_PARAM, objectSpecification, parameter);
-            parameterList.arrayAdd(linkBuilder.build());
+            parameterList.arrayAdd(
+                    ActionParameterDescriptionReprRenderer
+                    .newLinkToBuilder(getResourceContext(), Rel.ACTION_PARAM, objectSpecification, parameter)
+                    .build());
         }
 
         representation.mapPut("parameters", parameterList);
     }
 
-    protected void addLinkToElementTypeIfAny() {
-        final TypeOfFacet facet = getObjectFeature().getFacet(TypeOfFacet.class);
-        if (facet == null) {
-            return;
-        }
-        final ObjectSpecification typeOfSpec = facet.valueSpec();
-        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ELEMENT_TYPE, typeOfSpec);
-        getLinks().arrayAdd(linkBuilder.build());
+    private void addLinkToElementTypeIfAny() {
+        getObjectFeature()
+        .lookupFacet(TypeOfFacet.class)
+        .map(TypeOfFacet::valueSpec)
+        .ifPresent(typeOfSpec->
+            getLinks().arrayAdd(
+                DomainTypeReprRenderer
+                .newLinkToBuilder(getResourceContext(), Rel.ELEMENT_TYPE, typeOfSpec)
+                .build()));
     }
 
     private void addLinkToReturnTypeIfAny() {
-        final ObjectSpecification returnType = getObjectFeature().getReturnType();
-        if (returnType == null) {
+        val returnTypeSpec = getObjectFeature().getReturnType();
+        if (returnTypeSpec == null) {
             return;
         }
-        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.RETURN_TYPE, returnType);
-        getLinks().arrayAdd(linkBuilder.build());
-    }
-
-    @Override
-    protected void putExtensionsSpecificToFeature() {
-        putExtensionsName();
-        putExtensionsDescriptionIfAvailable();
+        getLinks().arrayAdd(
+                DomainTypeReprRenderer
+                .newLinkToBuilder(getResourceContext(), Rel.RETURN_TYPE, returnTypeSpec)
+                .build());
     }
 
 }
\ No newline at end of file
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
index 776973c..5aef51f 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domaintypes;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -29,18 +30,30 @@ import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 
-public class ActionParameterDescriptionReprRenderer extends AbstractTypeFeatureReprRenderer<ActionParameterDescriptionReprRenderer, ObjectActionParameter> {
+import lombok.val;
 
-    public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final ObjectActionParameter objectActionParameter) {
+public class ActionParameterDescriptionReprRenderer
+extends AbstractTypeFeatureReprRenderer<ObjectActionParameter> {
+
+    public static LinkBuilder newLinkToBuilder(
+            final IResourceContext resourceContext,
+            final Rel rel,
+            final ObjectSpecification objectSpecification,
+            final ObjectActionParameter objectActionParameter) {
         final String domainType = objectSpecification.getLogicalTypeName();
         final ObjectAction objectAction = objectActionParameter.getAction();
         final String actionId = objectAction.getId();
-        final String paramName = objectActionParameter.getName();
+        final String paramName = objectActionParameter
+                .getStaticFriendlyName()
+                .orElseThrow(_Exceptions::unexpectedCodeReach);;
         final String url = String.format("domain-types/%s/actions/%s/params/%s", domainType, actionId, paramName);
         return LinkBuilder.newBuilder(resourceContext, rel.andParam("id", deriveId(objectActionParameter)), RepresentationType.ACTION_PARAMETER_DESCRIPTION, url);
     }
 
-    public ActionParameterDescriptionReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public ActionParameterDescriptionReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.ACTION_PARAMETER_DESCRIPTION, representation);
     }
 
@@ -59,7 +72,10 @@ public class ActionParameterDescriptionReprRenderer extends AbstractTypeFeatureR
     }
 
     private static String deriveId(final ObjectActionParameter objectActionParameter) {
-        return objectActionParameter.getAction().getId() + "-" + objectActionParameter.getName();
+        val named = objectActionParameter
+                .getStaticFriendlyName()
+                .orElseThrow(_Exceptions::unexpectedCodeReach);
+        return objectActionParameter.getAction().getId() + "-" + named;
     }
 
     @Override
@@ -80,7 +96,9 @@ public class ActionParameterDescriptionReprRenderer extends AbstractTypeFeatureR
 
     @Override
     protected void addPropertiesSpecificToFeature() {
-        representation.mapPut("name", getObjectFeature().getName());
+        representation.mapPut("name", getObjectFeature()
+                .getStaticFriendlyName()
+                .orElseThrow(_Exceptions::unexpectedCodeReach));
         representation.mapPut("number", getObjectFeature().getNumber());
         representation.mapPut("optional", getObjectFeature().isOptional());
         getObjectFeature()
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
index 89355ae..51c8f2c 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
@@ -27,16 +27,26 @@ import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 
-public class CollectionDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<CollectionDescriptionReprRenderer, OneToManyAssociation> {
+import lombok.val;
 
-    public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final OneToManyAssociation collection) {
+public class CollectionDescriptionReprRenderer
+extends AbstractTypeMemberReprRenderer<OneToManyAssociation> {
+
+    public static LinkBuilder newLinkToBuilder(
+            final IResourceContext resourceContext,
+            final Rel rel,
+            final ObjectSpecification objectSpecification,
+            final OneToManyAssociation collection) {
         final String domainType = objectSpecification.getLogicalTypeName();
         final String collectionId = collection.getId();
         final String url = "domain-types/" + domainType + "/collections/" + collectionId;
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.COLLECTION_DESCRIPTION, url);
     }
 
-    public CollectionDescriptionReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public CollectionDescriptionReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.COLLECTION_DESCRIPTION, representation);
     }
 
@@ -45,19 +55,23 @@ public class CollectionDescriptionReprRenderer extends AbstractTypeMemberReprRen
         addLinkToElementTypeIfAny();
     }
 
-    private void addLinkToElementTypeIfAny() {
-        final ObjectSpecification elementType = getObjectFeature().getSpecification();
-        if (elementType == null) {
-            return;
-        }
-        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ELEMENT_TYPE, elementType);
-        getLinks().arrayAdd(linkBuilder.build());
-    }
-
     @Override
     protected void putExtensionsSpecificToFeature() {
         putExtensionsName();
         putExtensionsDescriptionIfAvailable();
     }
 
+    // -- HELPER
+
+    private void addLinkToElementTypeIfAny() {
+        val elementTypeSpec = getObjectFeature().getSpecification();
+        if (elementTypeSpec == null) {
+            return;
+        }
+        getLinks().arrayAdd(
+                DomainTypeReprRenderer
+                .newLinkToBuilder(getResourceContext(), Rel.ELEMENT_TYPE, elementTypeSpec)
+                .build());
+    }
+
 }
\ No newline at end of file
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
index 026d27c..58a0f00 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
@@ -33,7 +33,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
 import lombok.val;
 
-public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprRenderer, ObjectSpecification> {
+public class DomainTypeReprRenderer
+extends ReprRendererAbstract<ObjectSpecification> {
 
     public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpec) {
         final String typeFullName = objectSpec.getLogicalTypeName();
@@ -59,7 +60,7 @@ public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprR
     @Override
     public DomainTypeReprRenderer with(final ObjectSpecification objectSpecification) {
         this.objectSpecification = objectSpecification;
-        return cast(this);
+        return this;
     }
 
     @Override
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
index 3375ccd..611fb19 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
@@ -28,16 +28,26 @@ import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 
-public class PropertyDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<PropertyDescriptionReprRenderer, OneToOneAssociation> {
+import lombok.val;
 
-    public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
+public class PropertyDescriptionReprRenderer
+extends AbstractTypeMemberReprRenderer<OneToOneAssociation> {
+
+    public static LinkBuilder newLinkToBuilder(
+            final IResourceContext resourceContext,
+            final Rel rel,
+            final ObjectSpecification objectSpecification,
+            final OneToOneAssociation property) {
         final String domainType = objectSpecification.getLogicalTypeName();
         final String propertyId = property.getId();
         final String url = "domain-types/" + domainType + "/properties/" + propertyId;
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.PROPERTY_DESCRIPTION, url);
     }
 
-    public PropertyDescriptionReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public PropertyDescriptionReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.PROPERTY_DESCRIPTION, representation);
     }
 
@@ -54,14 +64,6 @@ public class PropertyDescriptionReprRenderer extends AbstractTypeMemberReprRende
             .ifPresent(maxLengthFacet->representation.mapPut("maxLength", maxLengthFacet.value()));
     }
 
-    private void addLinkToReturnTypeIfAny() {
-        final ObjectSpecification returnType = getObjectFeature().getSpecification();
-        if (returnType == null) {
-            return;
-        }
-        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.RETURN_TYPE, returnType);
-        getLinks().arrayAdd(linkBuilder.build());
-    }
 
     @Override
     protected void putExtensionsSpecificToFeature() {
@@ -69,4 +71,18 @@ public class PropertyDescriptionReprRenderer extends AbstractTypeMemberReprRende
         putExtensionsDescriptionIfAvailable();
     }
 
+    // -- HELPER
+
+    private void addLinkToReturnTypeIfAny() {
+        val returnTypeSpec = getObjectFeature().getSpecification();
+        if (returnTypeSpec == null) {
+            return;
+        }
+        getLinks().arrayAdd(
+                DomainTypeReprRenderer
+                .newLinkToBuilder(getResourceContext(), Rel.RETURN_TYPE, returnTypeSpec)
+                .build());
+    }
+
+
 }
\ No newline at end of file
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java
index a25f9b8..5dde58c 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java
@@ -27,20 +27,24 @@ import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-public class TypeActionResultReprRenderer extends ReprRendererAbstract<TypeActionResultReprRenderer, ObjectSpecification> {
+public class TypeActionResultReprRenderer
+extends ReprRendererAbstract<ObjectSpecification> {
 
     private ObjectSpecification objectSpecification;
     private LinkRepresentation selfLink;
     private Object value;
 
-    public TypeActionResultReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public TypeActionResultReprRenderer(
+            final IResourceContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.TYPE_ACTION_RESULT, representation);
     }
 
     @Override
     public TypeActionResultReprRenderer with(final ObjectSpecification objectSpecification) {
         this.objectSpecification = objectSpecification;
-        return cast(this);
+        return this;
     }
 
     public TypeActionResultReprRenderer withValue(final Object value) {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
index 837ca2f..5df8af5 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
@@ -29,7 +29,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
 public class TypeListReprRenderer
-extends ReprRendererAbstract<TypeListReprRenderer, Can<ObjectSpecification>> {
+extends ReprRendererAbstract<Can<ObjectSpecification>> {
 
     private Can<ObjectSpecification> specifications;
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index bb163f9..21d06b2 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -34,6 +34,7 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.domain.DomainObjectList;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
@@ -62,7 +63,7 @@ import lombok.NonNull;
 import lombok.val;
 
 /**
- * Rreturns representations according to the
+ * Returns representations according to the
  * <a href="https://restfulobjects.org">Restful Objects</a> spec.
  *
  * @since 1.x {@index}
@@ -71,7 +72,8 @@ import lombok.val;
 @Named("isis.viewer.ro.ContentNegotiationServiceForRestfulObjectsV1_0")
 @Priority(PriorityPrecedence.MIDPOINT)
 @Qualifier("RestfulObjectsV1_0")
-public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNegotiationService {
+public class ContentNegotiationServiceForRestfulObjectsV1_0
+implements ContentNegotiationService {
 
 
     protected final IsisConfiguration configuration;
@@ -129,7 +131,7 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
         ensureCompatibleAcceptHeader(RepresentationType.OBJECT_PROPERTY, resourceContext);
 
-        final ObjectPropertyReprRenderer renderer =
+        val renderer =
                 new ObjectPropertyReprRenderer(resourceContext)
                 .with(objectAndProperty)
                 .usingLinkTo(resourceContext.getObjectAdapterLinkTo());
@@ -180,7 +182,7 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
         ensureCompatibleAcceptHeader(RepresentationType.OBJECT_ACTION, resourceContext);
 
-        final ObjectActionReprRenderer renderer =
+        val renderer =
                 new ObjectActionReprRenderer(resourceContext)
                 .with(objectAndAction)
                 .usingLinkTo(resourceContext.getObjectAdapterLinkTo())
@@ -273,8 +275,11 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
                 if(buf.length() > 0) {
                     buf.append(",");
                 }
-                buf.append(param.getName()).append("=");
-                buf.append(abbreviated(titleOf(argAdapter), 8));
+                buf
+                .append(param.getStaticFriendlyName()
+                        .orElseThrow(_Exceptions::unexpectedCodeReach))
+                .append("=")
+                .append(abbreviated(titleOf(argAdapter), 8));
             }
         }
 
@@ -368,7 +373,7 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
          * Any unrecognized Accept headers will result in an HTTP Not Acceptable Response code (406).
          */
         STRICT;
-        static AcceptChecking fromConfig(IsisConfiguration configuration) {
+        static AcceptChecking fromConfig(final IsisConfiguration configuration) {
             return configuration.getViewer().getRestfulobjects().isStrictAcceptChecking()
                     ? AcceptChecking.STRICT
                     : AcceptChecking.RELAXED;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV2.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV2.java
index edf60a4..53cb0e5 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV2.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV2.java
@@ -370,10 +370,10 @@ public class ContentNegotiationServiceOrgApacheIsisV2 extends ContentNegotiation
             }
 
             final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
-            final ObjectPropertyReprRenderer renderer =
+            val renderer =
                     new ObjectPropertyReprRenderer(resourceContext, null, property.getId(), propertyRepresentation)
-                    .asStandalone();
-            renderer.with(ManagedProperty.of(objectAdapter, property, where));
+                    .asStandalone()
+                    .with(ManagedProperty.of(objectAdapter, property, where));
 
             final JsonRepresentation propertyValueRepresentation = renderer.render();
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
index 473cfd2..4615d12 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
@@ -124,19 +124,19 @@ class Generation {
         return swagger;
     }
 
-    private Map<String, Path> sorted(Map<String, Path> paths) {
+    private Map<String, Path> sorted(final Map<String, Path> paths) {
 
         final List<Map.Entry<String, Path>> entries = new ArrayList<>(paths.entrySet());
         entries.sort(new Comparator<Map.Entry<String, Path>>() {
             @Override
-            public int compare(Map.Entry<String, Path> o1, Map.Entry<String, Path> o2) {
+            public int compare(final Map.Entry<String, Path> o1, final Map.Entry<String, Path> o2) {
                 final String tag1 = tagFor(o1);
                 final String tag2 = tagFor(o2);
                 final int tag = tag1.compareTo(tag2);
                 return tag != 0 ? tag : o1.getKey().compareTo(o2.getKey());
             }
 
-            protected String tagFor(Map.Entry<String, Path> o1) {
+            protected String tagFor(final Map.Entry<String, Path> o1) {
                 return o1.getValue().getOperations().stream().findFirst().map(operation -> operation.getTags().stream().findFirst().orElse("(no tag)")).orElse("(no tag)");
             }
         });
@@ -450,11 +450,17 @@ class Generation {
             path.get(invokeOperation);
 
             for (final ObjectActionParameter parameter : parameters) {
+
+                val describedAs = parameter.getStaticDescription().orElse(null);
+
                 invokeOperation
                 .parameter(
                         new QueryParameter()
                         .name(parameter.getId())
-                        .description(Util.roSpec("2.9.1") + (!_Strings.isNullOrEmpty(parameter.getDescription())? (": " + parameter.getDescription()) : ""))
+                        .description(Util.roSpec("2.9.1")
+                                + (_Strings.isNotEmpty(describedAs)
+                                        ? (": " + describedAs)
+                                        : ""))
                         .required(false)
                         .type("string")
                         );
@@ -563,11 +569,17 @@ class Generation {
             path.get(invokeOperation);
 
             for (final ObjectActionParameter parameter : parameters) {
+
+                val describedAs = parameter.getStaticDescription().orElse(null);
+
                 invokeOperation
                 .parameter(
                         new QueryParameter()
                         .name(parameter.getId())
-                        .description(Util.roSpec("2.9.1") + (!_Strings.isNullOrEmpty(parameter.getDescription())? (": " + parameter.getDescription()) : ""))
+                        .description(Util.roSpec("2.9.1")
+                                + (_Strings.isNotEmpty(describedAs)
+                                        ? (": " + describedAs)
+                                        : ""))
                         .required(false)
                         .type("string")
                         );
@@ -768,7 +780,7 @@ class Generation {
         return new StringProperty();
     }
 
-    static StringProperty stringPropertyEnum(String... enumValues) {
+    static StringProperty stringPropertyEnum(final String... enumValues) {
         StringProperty stringProperty = stringProperty();
         stringProperty._enum(Arrays.asList(enumValues));
         if(enumValues.length >= 1) {
@@ -826,7 +838,7 @@ class Generation {
         return referencesCopy;
     }
 
-    private static Operation newOperation(String ... reprTypes) {
+    private static Operation newOperation(final String ... reprTypes) {
         Operation operation = new Operation()
                 .produces("application/json");
 
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/HomePageReprRenderer.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/HomePageReprRenderer.java
index 3ac0f69..7e4dd8f 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/HomePageReprRenderer.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/HomePageReprRenderer.java
@@ -37,7 +37,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.TypeListReprR
 
 import lombok.val;
 
-public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRenderer, Void> {
+public class HomePageReprRenderer
+extends ReprRendererAbstract<Void> {
 
     HomePageReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.HOME_PAGE, representation);
@@ -107,7 +108,7 @@ public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRende
         getLinks().arrayAdd(link);
     }
 
-    private void addLinkToServices(Stream<ManagedObject> serviceAdapters) {
+    private void addLinkToServices(final Stream<ManagedObject> serviceAdapters) {
 
         final JsonRepresentation link = LinkBuilder.newBuilder(
                 getResourceContext(),
@@ -135,7 +136,7 @@ public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRende
         getLinks().arrayAdd(link);
     }
 
-    private void addLinkToUser(InteractionContext authentication) {
+    private void addLinkToUser(final InteractionContext authentication) {
         final JsonRepresentation link = LinkBuilder.newBuilder(
                 getResourceContext(),
                 Rel.USER.getName(),
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
index 1440c67..54a50e7 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
@@ -45,7 +45,9 @@ public class ObjectAdapterUpdateHelper {
     private final ManagedObject objectAdapter;
     private final ResourceContext resourceContext;
 
-    public ObjectAdapterUpdateHelper(ResourceContext resourceContext, ManagedObject objectAdapter) {
+    public ObjectAdapterUpdateHelper(
+            final ResourceContext resourceContext,
+            final ManagedObject objectAdapter) {
         this.objectAdapter = objectAdapter;
         this.resourceContext = resourceContext;
     }
@@ -117,9 +119,9 @@ public class ObjectAdapterUpdateHelper {
             // otherwise, is an error.
             final String invalidReason = propertiesMap.getString("x-ro-invalidReason");
             if(invalidReason != null) {
-                propertiesMap.mapPut("x-ro-invalidReason", invalidReason + "; " + property.getName());
+                propertiesMap.mapPut("x-ro-invalidReason", invalidReason + "; " + property.getFriendlyName(objectAdapter.asProvider()));
             } else {
-                propertiesMap.mapPut("x-ro-invalidReason", "Mandatory field(s) missing: " + property.getName());
+                propertiesMap.mapPut("x-ro-invalidReason", "Mandatory field(s) missing: " + property.getFriendlyName(objectAdapter.asProvider()));
             }
             allOk = false;
             return allOk;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/UserReprRenderer.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/UserReprRenderer.java
index c3bf8b7..18e3db5 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/UserReprRenderer.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/UserReprRenderer.java
@@ -27,7 +27,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-public class UserReprRenderer extends ReprRendererAbstract<UserReprRenderer, InteractionContext> {
+public class UserReprRenderer
+extends ReprRendererAbstract<InteractionContext> {
 
     UserReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.USER, representation);
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/VersionReprRenderer.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/VersionReprRenderer.java
index 0f4be17..93c13cf 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/VersionReprRenderer.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/VersionReprRenderer.java
@@ -31,7 +31,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 import org.apache.isis.viewer.restfulobjects.viewer.jaxrsapp.RestfulObjectsSpec;
 
-public class VersionReprRenderer extends ReprRendererAbstract<VersionReprRenderer, Void> {
+public class VersionReprRenderer
+extends ReprRendererAbstract<Void> {
 
     private static final String META_INF_POM_PROPERTIES = "/META-INF/maven/org.apache.isis.viewer/isis-viewer-restfulobjects-server/pom.properties";
 
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 1b5bf71..4cf9925 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
@@ -77,17 +77,17 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
 
     // -- FACTORY METHODS
 
-    public static ActionModel of(EntityModel actionOwner, ObjectAction action) {
+    public static ActionModel of(final EntityModel actionOwner, final ObjectAction action) {
         return of(actionOwner, action.getMemento());
     }
 
-    public static ActionModel of(EntityModel actionOwner, ActionMemento actionMemento) {
+    public static ActionModel of(final EntityModel actionOwner, final ActionMemento actionMemento) {
         return new ActionModel(actionOwner, actionMemento);
     }
 
     public static ActionModel ofPageParameters(
-            IsisAppCommonContext commonContext,
-            PageParameters pageParameters) {
+            final IsisAppCommonContext commonContext,
+            final PageParameters pageParameters) {
 
         return PageParameterUtil.actionModelFor(commonContext, pageParameters);
     }
@@ -143,7 +143,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
                 getMetaModel());
     }
 
-    private ActionModel(EntityModel entityModel, ActionMemento actionMemento) {
+    private ActionModel(final EntityModel entityModel, final ActionMemento actionMemento) {
         super(entityModel.getCommonContext());
         this.ownerModel = entityModel;
         this.actionMemento = actionMemento;
@@ -152,7 +152,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
     /**
      * Copy constructor, as called by {@link #copy()}.
      */
-    private ActionModel(ActionModel actionModel) {
+    private ActionModel(final ActionModel actionModel) {
         super(actionModel.getCommonContext());
         this.ownerModel = actionModel.ownerModel;
         this.actionMemento = actionModel.actionMemento;
@@ -388,15 +388,15 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
         return inlinePromptContext;
     }
 
-    public void setInlinePromptContext(InlinePromptContext inlinePromptContext) {
+    public void setInlinePromptContext(final InlinePromptContext inlinePromptContext) {
         this.inlinePromptContext = inlinePromptContext;
     }
 
-    public void setParameterValue(ObjectActionParameter actionParameter, ManagedObject newParamValue) {
+    public void setParameterValue(final ObjectActionParameter actionParameter, final ManagedObject newParamValue) {
         argCache().setParameterValue(actionParameter, newParamValue);
     }
 
-    public void clearParameterValue(ObjectActionParameter actionParameter) {
+    public void clearParameterValue(final ObjectActionParameter actionParameter) {
         argCache().clearParameterValue(actionParameter);
     }
 
@@ -417,7 +417,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
 
     }
 
-    public void reassessPendingParamUiModels(int skipCount) {
+    public void reassessPendingParamUiModels(final int skipCount) {
 
         val pendingArgs = getArgumentsAsParamModel();
 
@@ -506,7 +506,7 @@ implements FormUiModel, FormExecutorContext, BookmarkableModel {
 
     // -- CLIENT SIDE CACHING ASPECTS ...
 
-    private static IRequestHandler enforceNoCacheOnClientSide(IRequestHandler downloadHandler){
+    private static IRequestHandler enforceNoCacheOnClientSide(final IRequestHandler downloadHandler){
         if(downloadHandler==null) {
             return downloadHandler;
         }
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 083d34f..70acb7e 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
@@ -54,7 +54,7 @@ implements ParameterUiModel {
      * object, with the {@link #getObject() value of this model} to be default
      * value (if any) of that action parameter.
      */
-    public ScalarParameterModel(EntityModel parentEntityModel, ActionParameterMemento paramMemento) {
+    public ScalarParameterModel(final EntityModel parentEntityModel, final ActionParameterMemento paramMemento) {
         super(parentEntityModel, paramMemento);
         this.paramMemento = paramMemento;
     }
@@ -132,7 +132,7 @@ implements ParameterUiModel {
 
     @Override
     public String toStringOf() {
-        return getName() + ": " + paramMemento.toString();
+        return getFriendlyName() + ": " + paramMemento.toString();
     }
 
     @Override
@@ -146,7 +146,7 @@ implements ParameterUiModel {
     }
 
     @Override
-    public void setValue(ManagedObject paramValue) {
+    public void setValue(final ManagedObject paramValue) {
         super.setObject(paramValue);
     }
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
index 91724bc..79e33cb 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
@@ -46,10 +46,10 @@ implements PropertyUiModel {
      * property.
      */
     public ScalarPropertyModel(
-            EntityModel parentEntityModel,
-            PropertyMemento propertyMemento,
-            EntityModel.Mode mode,
-            EntityModel.RenderingHint renderingHint) {
+            final EntityModel parentEntityModel,
+            final PropertyMemento propertyMemento,
+            final EntityModel.Mode mode,
+            final EntityModel.RenderingHint renderingHint) {
 
         super(parentEntityModel, propertyMemento, mode, renderingHint);
         this.propertyMemento = propertyMemento;
@@ -57,8 +57,8 @@ implements PropertyUiModel {
     }
 
     public ScalarPropertyModel copyHaving(
-            EntityModel.Mode mode,
-            EntityModel.RenderingHint renderingHint) {
+            final EntityModel.Mode mode,
+            final EntityModel.RenderingHint renderingHint) {
         return new ScalarPropertyModel(
                 getParentUiModel(),
                 propertyMemento,
@@ -142,7 +142,7 @@ implements PropertyUiModel {
 
     @Override
     public String toStringOf() {
-        return getName() + ": " + propertyMemento.toString();
+        return getFriendlyName() + ": " + propertyMemento.toString();
     }
 
     public String getReasonInvalidIfAny() {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actioninfo/ActionInfoPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actioninfo/ActionInfoPanel.java
index 27c005d..6dc18c1 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actioninfo/ActionInfoPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actioninfo/ActionInfoPanel.java
@@ -47,6 +47,6 @@ extends PanelAbstract<ManagedObject, ActionModel> {
         // TODO: render instead as links (providing isn't a service; provide a
         // component for this?)
         add(new Label(ID_TARGET, targetAdapter.titleString()));
-        add(new Label(ID_ACTION_NAME, objectAction.getName()));
+        add(new Label(ID_ACTION_NAME, objectAction.getFriendlyName(targetAdapter.asProvider())));
     }
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionprompt/ActionPromptHeaderPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionprompt/ActionPromptHeaderPanel.java
index 8290caf..402777c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionprompt/ActionPromptHeaderPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionprompt/ActionPromptHeaderPanel.java
@@ -23,7 +23,6 @@ import org.apache.wicket.model.IModel;
 
 import org.apache.isis.commons.internal.base._Blackhole;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.wicket.model.models.ActionModel;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
@@ -49,8 +48,7 @@ extends PanelAbstract<ManagedObject, ActionModel> {
             private static final long serialVersionUID = 1L;
             @Override
             public String getObject() {
-                final ObjectAction action = model.getMetaModel();
-                return action.getName();
+                return model.getFriendlyName();
             }
         });
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersPanel.java
index eee61bc..48dabe3 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersPanel.java
@@ -61,7 +61,7 @@ extends PanelAbstract<ManagedObject, ActionModel> {
      *
      * REVIEW: I wonder if this is necessary... there isn't anything exactly the same for property edits...
      */
-    public void setActionPrompt(ActionPrompt actionPrompt) {
+    public void setActionPrompt(final ActionPrompt actionPrompt) {
         ActionFormExecutorStrategy formExecutor = new ActionFormExecutorStrategy(getActionModel());
         formExecutor.setActionPrompt(actionPrompt);
     }
@@ -94,7 +94,7 @@ extends PanelAbstract<ManagedObject, ActionModel> {
         getComponentFactoryRegistry().addOrReplaceComponent(header, ComponentType.ENTITY_ICON_AND_TITLE, actionModel
                 .getParentUiModel());
 
-        final String actionName = getActionModel().getMetaModel().getName();
+        final String actionName = getActionModel().getFriendlyName();
         header.add(new Label(ID_ACTION_NAME, Model.of(actionName)));
 
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
index 1fb4b92..38d6891 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
@@ -48,6 +48,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
 import org.apache.isis.viewer.wicket.ui.components.collection.bulk.BulkActionsProvider;
@@ -158,7 +159,7 @@ implements CollectionCountProvider {
         val parentSpecIfAny =  collectionModel.parentedParentObjectSpecification()
                 .orElse(null);
 
-        val propertyById = _Maps.<String, ObjectAssociation>newLinkedHashMap();
+        val propertyById = _Maps.<String, OneToOneAssociation>newLinkedHashMap();
 
         elementTypeSpec.streamProperties(MixedIn.INCLUDED)
         .filter(property->property.streamFacets()
@@ -288,7 +289,7 @@ implements CollectionCountProvider {
         };
     }
 
-    private ObjectAdapterPropertyColumn createObjectAdapterPropertyColumn(final ObjectAssociation property) {
+    private ObjectAdapterPropertyColumn createObjectAdapterPropertyColumn(final OneToOneAssociation property) {
 
         val collectionModel = getModel();
 
@@ -308,7 +309,7 @@ implements CollectionCountProvider {
         return new ObjectAdapterPropertyColumn(
                 commonContext,
                 collectionModel.getVariant(),
-                Model.of(property.getName()),
+                Model.of(property.getColumnName()),
                 property.getId(),
                 property.getId(),
                 escaped,
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/summary/CollectionContentsAsSummary.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/summary/CollectionContentsAsSummary.java
index 0aae919..809306f 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/summary/CollectionContentsAsSummary.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/summary/CollectionContentsAsSummary.java
@@ -38,6 +38,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
 import org.apache.isis.viewer.wicket.ui.components.collection.count.CollectionCountProvider;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
@@ -87,8 +88,8 @@ implements CollectionCountProvider {
         feedback.setOutputMarkupId(true);
         addOrReplace(feedback);
 
-        final Stream<ObjectAssociation> numberAssociations = elementSpec
-                .streamAssociations(MixedIn.EXCLUDED)
+        final Stream<OneToOneAssociation> numberAssociations = elementSpec
+                .streamProperties(MixedIn.EXCLUDED)
                 .filter(CollectionContentsAsSummaryFactory.OF_TYPE_BIGDECIMAL);
 
         final RepeatingView repeating = new RepeatingView(ID_REPEATING_SUMMARY);
@@ -99,7 +100,7 @@ implements CollectionCountProvider {
 
             repeating.add(item);
 
-            String propertyName = numberAssociation.getName();
+            String propertyName = numberAssociation.getColumnName();
             item.add(new Label(ID_PROPERTY_NAME, new Model<String>(propertyName)));
 
 
@@ -123,11 +124,11 @@ implements CollectionCountProvider {
         private BigDecimal average;
         private String propertyName;
 
-        public Summary(List<ManagedObject> adapters, ObjectAssociation numberAssociation) {
+        public Summary(final List<ManagedObject> adapters, final ObjectAssociation numberAssociation) {
             this(null, adapters, numberAssociation);
         }
 
-        public Summary(String propertyName, List<ManagedObject> adapters, ObjectAssociation numberAssociation) {
+        public Summary(final String propertyName, final List<ManagedObject> adapters, final ObjectAssociation numberAssociation) {
             this.propertyName = propertyName;
             int nonNullCount = 0;
             for (val adapter : adapters) {
@@ -179,19 +180,19 @@ implements CollectionCountProvider {
             return asNumbers(getValues());
         }
 
-        private static List<Number> asNumbers(List<BigDecimal> values) {
+        private static List<Number> asNumbers(final List<BigDecimal> values) {
             return _Lists.map(values, Number.class::cast);
         }
 
 
     }
 
-    private void addItem(AbstractItem item, String id, BigDecimal amt) {
+    private void addItem(final AbstractItem item, final String id, final BigDecimal amt) {
         TextField<String> textField = new TextField<String>(id, new Model<String>(format(amt)));
         item.add(textField);
     }
 
-    private String format(BigDecimal amt) {
+    private String format(final BigDecimal amt) {
         return amt != null ? amt.setScale(2, RoundingMode.HALF_UP).toPlainString() : "";
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java
index d5bba72..14e7bd5 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java
@@ -31,6 +31,7 @@ import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
@@ -132,14 +133,15 @@ implements HasDynamicallyVisibleContent {
             div.addOrReplace(collectionPanel);
 
 
-            Label labelComponent = collectionPanel.createLabel(ID_COLLECTION_NAME, collectionMetaModel.getName());
+            final Label labelComponent = collectionPanel
+                    .createLabel(
+                            ID_COLLECTION_NAME,
+                            collectionMetaModel.getFriendlyName(collectionModel::getParentObject));
             labelComponent.setEscapeModelStrings(true);
             div.add(labelComponent);
 
-            final String description = collectionMetaModel.getDescription();
-            if(description != null) {
-                Tooltips.addTooltip(labelComponent, description);
-            }
+            _Strings.nonEmpty(collectionMetaModel.getDescription(collectionModel::getParentObject))
+            .ifPresent(description->Tooltips.addTooltip(labelComponent, description));
 
             final Can<LinkAndLabel> links = collectionModel.getLinks();
             AdditionalLinksPanel.addAdditionalLinks(div,ID_ADDITIONAL_LINKS, links, AdditionalLinksPanel.Style.INLINE_LIST);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java
index 3f84902..1899c65 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java
@@ -64,16 +64,16 @@ implements HasDynamicallyVisibleContent {
 
         for (val bs3Tab : tablist) {
             val repeatingViewWithDynamicallyVisibleContent = TabPanel.newRows(entityModel, bs3Tab);
+            // TODO[ISIS-1720] seems strange that viewer needs to do a translation here, should be already provided
             val translateContext = TranslationContext
                     .forTabIdentifier(entityModel.getTypeOfSpecification().getFeatureIdentifier());
-
             String bs3TabName = bs3Tab.getName();
             String tabName = translationService.translate(translateContext, bs3TabName);
             tabs.add(new AbstractTab(Model.of(tabName)) {
                 private static final long serialVersionUID = 1L;
 
                 @Override
-                public Panel getPanel(String panelId) {
+                public Panel getPanel(final String panelId) {
                     return new TabPanel(panelId, entityModel, bs3Tab, repeatingViewWithDynamicallyVisibleContent);
                 }
 
@@ -86,7 +86,7 @@ implements HasDynamicallyVisibleContent {
         return tabs;
     }
 
-    public TabGroupPanel(String id, final EntityModel entityModel, final BS3TabGroup bs3TabGroup) {
+    public TabGroupPanel(final String id, final EntityModel entityModel, final BS3TabGroup bs3TabGroup) {
         super(id, tabsFor(entityModel, bs3TabGroup));
         this.entityModel = entityModel;
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditPanel.java
index 1ac1c3c..21fcd03 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditPanel.java
@@ -88,8 +88,7 @@ extends PanelAbstract<ManagedObject, ScalarPropertyModel> {
         getComponentFactoryRegistry().addOrReplaceComponent(this, ComponentType.PROPERTY_EDIT_FORM, getScalarModel());
         getComponentFactoryRegistry().addOrReplaceComponent(header, ComponentType.ENTITY_ICON_AND_TITLE, scalarModel.getParentUiModel());
 
-        val property = getScalarModel().getMetaModel();
-        val propertyName = property.getName();
+        val propertyName = getScalarModel().getFriendlyName();
         val label = new Label(ID_PROPERTY_NAME, Model.of(propertyName));
 
         label.setEscapeModelStrings(true);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/propertyheader/PropertyEditPromptHeaderPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/propertyheader/PropertyEditPromptHeaderPanel.java
index 6016dd3..346448b 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/propertyheader/PropertyEditPromptHeaderPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/propertyheader/PropertyEditPromptHeaderPanel.java
@@ -50,7 +50,7 @@ extends PanelAbstract<ManagedObject, ScalarPropertyModel> {
 
             @Override
             public String getObject() {
-                return model.getName();
+                return model.getFriendlyName();
             }
         });
 
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 3bda3fb..200b4a6 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
@@ -85,7 +85,7 @@ public abstract class ScalarPanelSelectAbstract extends ScalarPanelAbstract {
         setOutputMarkupId(true);
         select2.component().setOutputMarkupId(true);
 
-        final String name = scalarModel.getName();
+        final String name = scalarModel.getFriendlyName();
         select2.setLabel(Model.of(name));
 
         final FormGroup formGroup = createFormGroupAndName(formComponent, ID_SCALAR_IF_REGULAR, ID_SCALAR_NAME);
@@ -211,7 +211,7 @@ public abstract class ScalarPanelSelectAbstract extends ScalarPanelAbstract {
      * @param target The Ajax request handler
      */
     @Override
-    public void repaint(AjaxRequestTarget target) {
+    public void repaint(final AjaxRequestTarget target) {
         //target.add(select2.component());
         target.add(this);
     }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
index fd5eebf..10d14b0 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
@@ -165,7 +165,7 @@ implements TextFieldValueModel.ScalarModelProvider {
 
     protected MarkupContainer createScalarIfRegularFormGroup() {
         Fragment textFieldFragment = createTextFieldFragment("scalarValueContainer");
-        final String name = getModel().getName();
+        final String name = getModel().getFriendlyName();
         textField.setLabel(Model.of(name));
 
         final FormGroup formGroup = new FormGroup(ID_SCALAR_IF_REGULAR, this.textField);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java
index 48d6f58..1f3f75d 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/blobclob/IsisBlobOrClobPanelAbstract.java
@@ -78,12 +78,12 @@ extends ScalarPanelAbstract {
     @Override
     protected FormGroup createComponentForRegular() {
         fileUploadField = createFileUploadField(ID_SCALAR_VALUE);
-        fileUploadField.setLabel(Model.of(getModel().getName()));
+        fileUploadField.setLabel(Model.of(getModel().getFriendlyName()));
 
         final FormGroup scalarIfRegularFormGroup = new FormGroup(ID_SCALAR_IF_REGULAR, fileUploadField);
         scalarIfRegularFormGroup.add(fileUploadField);
 
-        final Label scalarName = new Label(ID_SCALAR_NAME, getModel().getName());
+        final Label scalarName = new Label(ID_SCALAR_NAME, getModel().getFriendlyName());
         scalarIfRegularFormGroup.add(scalarName);
 
         wicketImage = asWicketImage(ID_IMAGE);
@@ -131,7 +131,7 @@ extends ScalarPanelAbstract {
 
     // //////////////////////////////////////
 
-    private Image asWicketImage(String id) {
+    private Image asWicketImage(final String id) {
 
         val adapter = getModel().getObject();
         if(adapter == null) {
@@ -166,7 +166,7 @@ extends ScalarPanelAbstract {
         updateRegularFormComponents(InputFieldVisibility.VISIBLE, InputFieldEditability.EDITABLE, null, Optional.empty());
     }
 
-    private FileUploadField createFileUploadField(String componentId) {
+    private FileUploadField createFileUploadField(final String componentId) {
         final BootstrapFileInputField fileUploadField = new BootstrapFileInputField(
                 componentId, new IModel<List<FileUpload>>() {
 
@@ -219,7 +219,7 @@ extends ScalarPanelAbstract {
         return adapter != null? (T) adapter.getPojo(): null;
     }
 
-    public IsisBlobOrClobPanelAbstract(String id, ScalarModel scalarModel) {
+    public IsisBlobOrClobPanelAbstract(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel);
     }
 
@@ -298,7 +298,7 @@ extends ScalarPanelAbstract {
         return scalarModel.getFileAccept();
     }
 
-    private void addAcceptFilterTo(Component component){
+    private void addAcceptFilterTo(final Component component){
         final String filter = getAcceptFilter();
         if(component==null || filter==null || filter.isEmpty())
             return; // ignore
@@ -312,7 +312,7 @@ extends ScalarPanelAbstract {
         component.add(new AttributeModifier("accept", new AcceptAttributeModel()));
     }
 
-    private Label updateFileNameLabel(String idFileName, MarkupContainer formComponent) {
+    private Label updateFileNameLabel(final String idFileName, final MarkupContainer formComponent) {
         class FileNameModel extends Model<String> {
             private static final long serialVersionUID = 1L;
             @Override
@@ -340,7 +340,7 @@ extends ScalarPanelAbstract {
             private static final long serialVersionUID = 1L;
 
             @Override
-            public void onClick(AjaxRequestTarget target) {
+            public void onClick(final AjaxRequestTarget target) {
                 setEnabled(false);
                 ScalarModel model = IsisBlobOrClobPanelAbstract.this.getModel();
                 model.setObject(null);
@@ -364,7 +364,7 @@ extends ScalarPanelAbstract {
 
     }
 
-    private MarkupContainer updateDownloadLink(String downloadId, MarkupContainer container) {
+    private MarkupContainer updateDownloadLink(final String downloadId, final MarkupContainer container) {
         val resourceLink = createResourceLink(downloadId);
         if(resourceLink != null) {
             container.addOrReplace(resourceLink);
@@ -374,7 +374,7 @@ extends ScalarPanelAbstract {
         return resourceLink;
     }
 
-    private ResourceLinkVolatile createResourceLink(String id) {
+    private ResourceLinkVolatile createResourceLink(final String id) {
         final T blob = getBlobOrClobFromModel();
         if(blob == null) {
             return null;
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanel.java
index a733fa7..297ce6a 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanel.java
@@ -45,7 +45,7 @@ extends PanelAbstract<ManagedObject, ScalarModel> {
     }
 
     private void buildGui() {
-        val scalarName = getModel().getName();
+        val scalarName = getModel().getFriendlyName();
         val scalarNameLabel = new Label(ID_SCALAR_NAME, scalarName);
         addOrReplace(scalarNameLabel);
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java
index 3fd107f..f5f5205 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java
@@ -37,9 +37,9 @@ public class ParentedMarkupPanel extends ScalarPanelTextFieldParseableAbstract {
     private final transient MarkupComponentFactory markupComponentFactory;
 
     public ParentedMarkupPanel(
-            String id,
-            ScalarModel scalarModel,
-            MarkupComponentFactory markupComponentFactory) {
+            final String id,
+            final ScalarModel scalarModel,
+            final MarkupComponentFactory markupComponentFactory) {
 
         super(id, scalarModel);
         this.markupComponentFactory = markupComponentFactory;
@@ -61,7 +61,7 @@ public class ParentedMarkupPanel extends ScalarPanelTextFieldParseableAbstract {
         final MarkupComponent markupComponent =
                 createMarkupComponent("scalarValueContainer");
 
-        getTextField().setLabel(Model.of(getModel().getName()));
+        getTextField().setLabel(Model.of(getModel().getFriendlyName()));
 
         final FormGroup formGroup = new FormGroup(ID_SCALAR_IF_REGULAR, getTextField());
         formGroup.add(markupComponent);
@@ -79,7 +79,7 @@ public class ParentedMarkupPanel extends ScalarPanelTextFieldParseableAbstract {
         return createMarkupComponent(ID_SCALAR_IF_COMPACT);
     }
 
-    protected MarkupComponent createMarkupComponent(String id) {
+    protected MarkupComponent createMarkupComponent(final String id) {
         return markupComponentFactory.newMarkupComponent(id, getModel());
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
index 5a00a7b..9b3cc85 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
@@ -60,7 +60,7 @@ public class BooleanPanel extends ScalarPanelAbstract {
 
     @Override
     protected MarkupContainer createComponentForRegular() {
-        final String name = getModel().getName();
+        final String name = getModel().getFriendlyName();
 
         checkBox = createCheckBox(ID_SCALAR_VALUE, CheckBoxXConfig.Sizes.lg);
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index 8d90f40..ee6714e 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -83,7 +83,7 @@ public class ReferencePanel extends ScalarPanelSelectAbstract {
     protected Component createComponentForCompact() {
 
         final ScalarModel scalarModel = getModel();
-        final String name = scalarModel.getName();
+        final String name = scalarModel.getFriendlyName();
 
         entitySimpleLink = (EntityLinkSimplePanel) getComponentFactoryRegistry()
                 .createComponent(ComponentType.ENTITY_LINK, scalarModel);
@@ -128,13 +128,13 @@ public class ReferencePanel extends ScalarPanelSelectAbstract {
         // (as per the isEditableWithEitherAutoCompleteOrChoices() guard above)
         if(getModel().hasChoices()) {
 
-            settings.setPlaceholder(getModel().getName());
+            settings.setPlaceholder(getModel().getFriendlyName());
 
         } else if(getModel().hasAutoComplete()) {
 
             final int minLength = getModel().getAutoCompleteMinLength();
             settings.setMinimumInputLength(minLength);
-            settings.setPlaceholder(getModel().getName());
+            settings.setPlaceholder(getModel().getFriendlyName());
 
         } else if(hasObjectAutoComplete()) {
             final ObjectSpecification typeOfSpecification = getModel().getTypeOfSpecification();
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java
index 8be7752..93806a9 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java
@@ -67,7 +67,7 @@ implements CollectionCountProvider, CollectionSelectorProvider {
 
         ActionModel actionModel = collectionModel.getActionModel();
         ObjectAction action = actionModel.getMetaModel();
-        outerDiv.addOrReplace(new Label(StandaloneCollectionPanel.ID_ACTION_NAME, Model.of(action.getName())));
+        outerDiv.addOrReplace(new Label(StandaloneCollectionPanel.ID_ACTION_NAME, Model.of(actionModel.getFriendlyName())));
 
         CssClassAppender.appendCssClassTo(outerDiv,
                 CssClassAppender.asCssStyle("isis-" + action.getOnType().getLogicalTypeName().replace('.', '-') + "-" + action.getId()));
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanel.java
index 860c4ce..8273948 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanel.java
@@ -57,7 +57,7 @@ public class TreePanel extends ScalarPanelTextFieldParseableAbstract {
         final Behavior treeTheme = getTreeThemeProvider().treeThemeFor(super.getModel());
 
 
-        getTextField().setLabel(Model.of(getModel().getName()));
+        getTextField().setLabel(Model.of(getModel().getFriendlyName()));
 
         final FormGroup formGroup = new FormGroup(ID_SCALAR_IF_REGULAR, getTextField());
         formGroup.add(treeComponent);
@@ -83,7 +83,7 @@ public class TreePanel extends ScalarPanelTextFieldParseableAbstract {
 
     // -- HELPER
 
-    private Component createTreeComponent(String id) {
+    private Component createTreeComponent(final String id) {
         return IsisToWicketTreeAdapter.adapt(id, getModel());
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java
index b0fcfcd..8c93f03 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java
@@ -183,8 +183,7 @@ implements Serializable {
                     private static final long serialVersionUID = 1L;
                     @Override
                     public String getObject() {
-                        final ObjectAction action = actionModel.getMetaModel();
-                        return action.getName();
+                        return actionModel.getFriendlyName();
                     }
                 });
                 prompt.setTitle(label, target);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/standalonecollection/StandaloneCollectionPage.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/standalonecollection/StandaloneCollectionPage.java
index 01a8406..2ae6b3d 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/standalonecollection/StandaloneCollectionPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/standalonecollection/StandaloneCollectionPage.java
@@ -40,7 +40,7 @@ public class StandaloneCollectionPage extends PageAbstract {
      */
     public StandaloneCollectionPage(final EntityCollectionModelStandalone collectionModel) {
         super(PageParametersUtils.newPageParameters(),
-                collectionModel.getActionModel().getMetaModel().getName(),
+                collectionModel.getActionModel().getFriendlyName(),
                 ComponentType.STANDALONE_COLLECTION);
 
         addChildComponents(themeDiv, collectionModel);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/value/ValuePage.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/value/ValuePage.java
index 93e6a93..ff9d6ee 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/value/ValuePage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/value/ValuePage.java
@@ -48,7 +48,7 @@ public class ValuePage extends PageAbstract {
     }
 
 
-    private ValuePage(ValueModel valueModel, String actionName) {
+    private ValuePage(final ValueModel valueModel, final String actionName) {
         super(PageParametersUtils.newPageParameters(), actionName, ComponentType.VALUE);
 
         themeDiv.addOrReplace(new Label(ID_ACTION_NAME, actionName));
@@ -62,7 +62,7 @@ public class ValuePage extends PageAbstract {
     private static String actionNameFrom(final ValueModel valueModel) {
         ActionModel actionModel = valueModel.getActionModelHint();
         if(actionModel != null) {
-            return actionModel.getMetaModel().getName();
+            return actionModel.getFriendlyName();
         }
         return "Results"; // fallback, probably not required because hint should always exist on the model.
     }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/voidreturn/VoidReturnPage.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/voidreturn/VoidReturnPage.java
index abd61c2..172b147 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/voidreturn/VoidReturnPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/voidreturn/VoidReturnPage.java
@@ -55,7 +55,7 @@ public class VoidReturnPage extends PageAbstract {
     private static String actionNameFrom(final VoidModel model) {
         ActionModel actionModel = model.getActionModelHint();
         if(actionModel != null) {
-            return actionModel.getMetaModel().getName();
+            return actionModel.getFriendlyName();
         }
         return "Results"; // fallback, probably not required because hint should always exist on the model.
     }