You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/09/06 15:46:21 UTC

[isis] 02/02: ISIS-2866: ensures @MemberSupport everywhere; converts service actions to local mixins.

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

danhaywood pushed a commit to branch ISIS-2867
in repository https://gitbox.apache.org/repos/asf/isis.git

commit de1f19399550d9a1b550bb651d6e368860620680
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Sep 6 16:45:57 2021 +0100

    ISIS-2866: ensures @MemberSupport everywhere; converts service actions to local mixins.
---
 .../services/confview/ConfigurationMenu.java       |  19 +-
 .../applib/services/layout/LayoutServiceMenu.java  |  63 ++--
 .../services/metamodel/MetaModelServiceMenu.java   | 373 ++++++++++-----------
 .../isis/applib/services/user/ImpersonateMenu.java | 143 ++++----
 .../applib/services/user/ImpersonateStopMenu.java  |  24 +-
 .../isis/applib/services/userui/UserMenu.java      |  22 +-
 .../primary/mixins/Object_openOnSecondary.java     |  11 +-
 .../primary/ui/CommandReplayOnPrimaryService.java  | 194 ++++++-----
 .../ui/CommandReplayOnSecondaryService.java        |  51 +--
 ...OrphanedPermissionManager_relocateSelected.java |   5 +-
 .../dom/mixins/ApplicationPermission_allow.java    |   5 +-
 .../dom/mixins/ApplicationPermission_changing.java |   5 +-
 .../dom/mixins/ApplicationPermission_delete.java   |   3 +-
 .../dom/mixins/ApplicationPermission_feature.java  |  12 +-
 .../mixins/ApplicationPermission_updateRole.java   |  12 +-
 .../dom/mixins/ApplicationPermission_veto.java     |   6 +-
 .../dom/mixins/ApplicationPermission_viewing.java  |   5 +-
 .../permission/menu/ApplicationPermissionMenu.java |  39 ++-
 .../dom/mixins/ApplicationRole_addPermission.java  |  15 +-
 .../role/dom/mixins/ApplicationRole_addUser.java   |   6 +-
 .../role/dom/mixins/ApplicationRole_delete.java    |   6 +-
 .../mixins/ApplicationRole_removePermissions.java  |   3 +-
 .../dom/mixins/ApplicationRole_removeUsers.java    |   7 +-
 .../mixins/ApplicationRole_updateDescription.java  |   8 +-
 .../dom/mixins/ApplicationRole_updateName.java     |   8 +-
 .../applib/role/menu/ApplicationRoleMenu.java      |  70 ++--
 .../dom/mixins/ApplicationTenancy_addChild.java    |   3 +-
 .../dom/mixins/ApplicationTenancy_addUser.java     |   6 +-
 .../dom/mixins/ApplicationTenancy_delete.java      |   3 +-
 .../dom/mixins/ApplicationTenancy_removeChild.java |  12 +-
 .../dom/mixins/ApplicationTenancy_removeUser.java  |  12 +-
 .../dom/mixins/ApplicationTenancy_updateName.java  |   8 +-
 .../dom/mixins/ApplicationTenancy_users.java       |   3 +-
 .../tenancy/menu/ApplicationTenancyMenu.java       |  76 +++--
 .../applib/user/app/ApplicationUserManager.java    |   5 +-
 .../mixins/ApplicationUserManager_allUsers.java    |   3 +-
 .../ApplicationUserManager_newDelegateUser.java    |   6 +-
 .../ApplicationUserManager_newLocalUser.java       |   9 +-
 .../user/contributions/HasUsername_open.java       |  15 +-
 .../secman/applib/user/dom/ApplicationUser.java    |  14 +-
 .../user/dom/mixins/ApplicationUser_addRole.java   |   9 +-
 .../user/dom/mixins/ApplicationUser_delete.java    |   6 +-
 .../user/dom/mixins/ApplicationUser_duplicate.java |   7 +-
 .../user/dom/mixins/ApplicationUser_lock.java      |   6 +-
 .../dom/mixins/ApplicationUser_removeRoles.java    |   3 +-
 .../dom/mixins/ApplicationUser_resetPassword.java  |   9 +-
 .../user/dom/mixins/ApplicationUser_unlock.java    |   6 +-
 .../mixins/ApplicationUser_updateAccountType.java  |   7 +-
 .../dom/mixins/ApplicationUser_updateAtPath.java   |   6 +-
 .../mixins/ApplicationUser_updateEmailAddress.java |   9 +-
 .../mixins/ApplicationUser_updateFaxNumber.java    |  12 +-
 .../dom/mixins/ApplicationUser_updateName.java     |  27 +-
 .../dom/mixins/ApplicationUser_updatePassword.java |  16 +-
 .../mixins/ApplicationUser_updatePhoneNumber.java  |  12 +-
 .../dom/mixins/ApplicationUser_updateUsername.java |   8 +-
 ...ApplicationUser_effectiveMemberPermissions.java |   3 +-
 ...ationUser_filterEffectiveMemberPermissions.java |   6 +-
 .../dom/mixins/perms/UserPermissionViewModel.java  |   7 +-
 .../applib/user/menu/ApplicationUserMenu.java      |  38 ++-
 .../secman/applib/user/menu/MeService.java         |  49 +--
 .../jdo/metamodel/menu/JdoMetamodelMenu.java       |  19 +-
 .../service/swagger/SwaggerServiceMenu.java        |  83 +++--
 62 files changed, 781 insertions(+), 857 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/confview/ConfigurationMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/confview/ConfigurationMenu.java
index 20392f0..3e3a830 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/confview/ConfigurationMenu.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/confview/ConfigurationMenu.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.annotation.SemanticsOf;
@@ -53,25 +54,25 @@ public class ConfigurationMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE_CONF + ".ConfigurationMenu";
 
-    public static abstract class ActionDomainEvent
-            extends IsisModuleApplib.ActionDomainEvent<ConfigurationMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleApplib.ActionDomainEvent<T> {}
 
     final FactoryService factoryService;
 
 
-    public static class ConfigurationDomainEvent
-            extends ActionDomainEvent {}
-
     @Action(
-            domainEvent = ConfigurationDomainEvent.class,
+            domainEvent = configuration.ActionEvent.class,
             semantics = SemanticsOf.SAFE
     )
     @ActionLayout(
             cssClassFa = "fa-wrench",
             sequence = "500.900.1")
-    public ConfigurationViewmodel configuration(){
-        return factoryService.viewModel(new ConfigurationViewmodel());
-    }
+    public class configuration{
 
+        public class ActionEvent extends ActionDomainEvent<configuration> {}
+
+        @MemberSupport public ConfigurationViewmodel act(){
+            return factoryService.viewModel(new ConfigurationViewmodel());
+        }
+    }
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/layout/LayoutServiceMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/layout/LayoutServiceMenu.java
index ee56a91..078067e 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/layout/LayoutServiceMenu.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/layout/LayoutServiceMenu.java
@@ -20,7 +20,6 @@ package org.apache.isis.applib.services.layout;
 
 import javax.activation.MimeType;
 import javax.activation.MimeTypeParseException;
-import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.apache.isis.applib.IsisModuleApplib;
@@ -55,12 +54,13 @@ public class LayoutServiceMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE + ".LayoutServiceMenu";
 
-    public static abstract class ActionDomainEvent
-    extends IsisModuleApplib.ActionDomainEvent<LayoutServiceMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleApplib.ActionDomainEvent<T> {}
 
+    private final LayoutService layoutService;
     private final MimeType mimeTypeApplicationZip;
 
-    public LayoutServiceMenu() {
+    public LayoutServiceMenu(final LayoutService layoutService) {
+        this.layoutService = layoutService;
         try {
             mimeTypeApplicationZip = new MimeType("application", "zip");
         } catch (final MimeTypeParseException ex) {
@@ -68,10 +68,9 @@ public class LayoutServiceMenu {
         }
     }
 
-    public static class DownloadLayoutsDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = DownloadLayoutsDomainEvent.class,
+            domainEvent = downloadLayouts.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -79,25 +78,25 @@ public class LayoutServiceMenu {
             cssClassFa = "fa-download",
             named = "Download Object Layouts (ZIP)",
             sequence="500.400.1")
-    // ...
-    public Blob downloadLayouts(final Style style) {
+    public class downloadLayouts{
 
-        final String fileName = "layouts." + style.name().toLowerCase() + ".zip";
+        public class ActionEvent extends ActionDomainEvent<downloadLayouts> {}
 
-        final byte[] zipBytes = layoutService.toZip(style);
-        return new Blob(fileName, mimeTypeApplicationZip, zipBytes);
-        // ...
-    }
+        @MemberSupport public Blob act(final Style style) {
+
+            final String fileName = "layouts." + style.name().toLowerCase() + ".zip";
 
-    @MemberSupport
-    public Style default0DownloadLayouts() {
-        return Style.NORMALIZED;
+            final byte[] zipBytes = layoutService.toZip(style);
+            return new Blob(fileName, mimeTypeApplicationZip, zipBytes);
+        }
+
+        @MemberSupport public Style default0Act() { return Style.NORMALIZED; }
     }
 
-    public static class DownloadMenuBarsLayoutDomainEvent extends ActionDomainEvent {}
+
 
     @Action(
-            domainEvent = DownloadMenuBarsLayoutDomainEvent.class,
+            domainEvent = downloadMenuBarsLayout.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -105,27 +104,21 @@ public class LayoutServiceMenu {
             cssClassFa = "fa-download",
             named = "Download Menu Bars Layout (XML)",
             sequence="500.400.2")
-    // ...
-    public Clob downloadMenuBarsLayout(
-            @ParameterLayout(named = "File name") final String fileName,
-            final MenuBarsService.Type type) {
+    public class downloadMenuBarsLayout{
 
-        final String xml = layoutService.toMenuBarsXml(type);
+        public class ActionEvent extends ActionDomainEvent<downloadMenuBarsLayout> {}
 
-        return new Clob(_Strings.asFileNameWithExtension(fileName,  ".xml"), "text/xml", xml);
-        // ...
-    }
+        @MemberSupport public Clob act(
+                @ParameterLayout(named = "File name") final String fileName,
+                final MenuBarsService.Type type) {
 
-    @MemberSupport
-    public String default0DownloadMenuBarsLayout() {
-        return "menubars.layout.xml";
-    }
+            final String xml = layoutService.toMenuBarsXml(type);
 
-    @MemberSupport
-    public MenuBarsService.Type default1DownloadMenuBarsLayout() {
-        return MenuBarsService.Type.DEFAULT;
-    }
+            return new Clob(_Strings.asFileNameWithExtension(fileName,  ".xml"), "text/xml", xml);
+        }
 
-    @Inject LayoutService layoutService;
+        @MemberSupport public String default0Act() { return "menubars.layout.xml"; }
+        @MemberSupport public MenuBarsService.Type default1Act() { return MenuBarsService.Type.DEFAULT; }
+    }
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelServiceMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelServiceMenu.java
index bc5c289..20e9b30 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelServiceMenu.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelServiceMenu.java
@@ -69,14 +69,11 @@ public class MetaModelServiceMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE + ".MetaModelServiceMenu";
 
-    public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<MetaModelServiceMenu> { }
+    public static abstract class ActionDomainEvent<T> extends IsisModuleApplib.ActionDomainEvent<T> { }
 
-    // -- CSV
-
-    public static class DownloadMetaModelEvent extends ActionDomainEvent { }
 
     @Action(
-            domainEvent = DownloadMetaModelEvent.class,
+            domainEvent = downloadMetaModelCsv.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -84,30 +81,31 @@ public class MetaModelServiceMenu {
             cssClassFa = "fa-download",
             named = "Download Meta Model (CSV)",
             sequence="500.500.2")
-    public Blob downloadMetaModelCsv(
-            @ParameterLayout(named = ".csv file name")
-            final String csvFileName) {
-
-        final DomainModel domainModel =  metaModelService.getDomainModel();
-        final StringBuilder csv = _CsvExport.toCsv(domainModel);
-        
-        return Clob.of(csvFileName, CommonMimeType.CSV, csv)
-                .toBlob(UTF_8)
-                .zip();
-
-        // ...
-    }
+    public class downloadMetaModelCsv {
+
+        public class ActionEvent extends ActionDomainEvent<downloadMetaModelCsv> { }
+
+        @MemberSupport public Blob act(
+                @ParameterLayout(named = ".csv file name")
+                final String csvFileName) {
+
+            final DomainModel domainModel =  metaModelService.getDomainModel();
+            final StringBuilder csv = _CsvExport.toCsv(domainModel);
+
+            return Clob.of(csvFileName, CommonMimeType.CSV, csv)
+                    .toBlob(UTF_8)
+                    .zip();
+        }
+
+        @MemberSupport public String default0Act() {
+            return "metamodel.csv";
+        }
 
-    @MemberSupport
-    public String default0DownloadMetaModelCsv() {
-        return "metamodel.csv";
     }
 
-    // -- XML
 
-    public static class DownloadMetaModelXmlEvent extends ActionDomainEvent { }
     @Action(
-            domainEvent = DownloadMetaModelXmlEvent.class,
+            domainEvent = downloadMetaModelXml.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -115,72 +113,62 @@ public class MetaModelServiceMenu {
             cssClassFa = "fa-download",
             named = "Download Meta Model (XML)",
             sequence="500.500.2")
-    public Blob downloadMetaModelXml(
-            @ParameterLayout(named = ".xml file name")
-            final String fileName,
-
-            @ParameterLayout(named = "Namespaces",
-            describedAs="Subset of the complete meta model, only including namespaces starting with given prefix")
-            final List<String> namespaces,
-
-            @ParameterLayout(named = "Ignore Interfaces")
-            @Parameter(optionality=Optionality.MANDATORY)
-            final boolean ignoreInterfaces
-            ) {
-
-        Config config =
-                new Config()
-                .withIgnoreNoop()
-                .withIgnoreAbstractClasses()
-                .withIgnoreInterfaces()
-                .withIgnoreBuiltInValueTypes();
-        for (final String namespace : namespaces) {
-            config = config.withNamespacePrefix(namespace);
-        }
-        if(ignoreInterfaces) {
-            config = config.withIgnoreInterfaces();
-        }
-
-        final MetamodelDto metamodelDto =  metaModelService.exportMetaModel(config);
-
-        final String xml = jaxbService.toXml(metamodelDto);
+    public class downloadMetaModelXml{
+
+        public class ActionEvent extends ActionDomainEvent<downloadMetaModelXml> { }
+
+        @MemberSupport public Blob act(
+                @ParameterLayout(named = ".xml file name")
+                final String fileName,
+
+                @ParameterLayout(named = "Namespaces",
+                        describedAs="Subset of the complete meta model, only including namespaces starting with given prefix")
+                final List<String> namespaces,
+
+                @ParameterLayout(named = "Ignore Interfaces")
+                @Parameter(optionality=Optionality.MANDATORY)
+                final boolean ignoreInterfaces
+        ) {
+
+            Config config =
+                    new Config()
+                            .withIgnoreNoop()
+                            .withIgnoreAbstractClasses()
+                            .withIgnoreInterfaces()
+                            .withIgnoreBuiltInValueTypes();
+            for (final String namespace : namespaces) {
+                config = config.withNamespacePrefix(namespace);
+            }
+            if(ignoreInterfaces) {
+                config = config.withIgnoreInterfaces();
+            }
 
-        return Clob.of(fileName, CommonMimeType.XML, xml)
-                .toBlob(UTF_8)
-                .zip();
+            final MetamodelDto metamodelDto =  metaModelService.exportMetaModel(config);
 
-        // ...
-    }
+            final String xml = jaxbService.toXml(metamodelDto);
 
-    @MemberSupport
-    public String validateDownloadMetaModelXml(
-            final String fileName, final List<String> namespacePrefixes, final boolean ignoreInterfaces) {
-        if(namespacePrefixes == null || namespacePrefixes.isEmpty()) {
-            return "At least one package must be selected";
+            return Clob.of(fileName, CommonMimeType.XML, xml)
+                    .toBlob(UTF_8)
+                    .zip();
         }
-        return null;
-    }
 
-    @MemberSupport
-    public String default0DownloadMetaModelXml() {
-        return "metamodel.xml";
-    }
+        @MemberSupport public String validateAct(
+                final String fileName, final List<String> namespacePrefixes, final boolean ignoreInterfaces) {
+            if(namespacePrefixes == null || namespacePrefixes.isEmpty()) {
+                return "At least one package must be selected";
+            }
+            return null;
+        }
 
-    @MemberSupport
-    public List<String> choices1DownloadMetaModelXml() {
-        return namespaceChoices();
-    }
+        @MemberSupport public String default0Act() { return "metamodel.xml"; }
+        @MemberSupport public List<String> choices1Act() { return namespaceChoices(); }
+        @MemberSupport public boolean default2Act() { return true; }
 
-    @MemberSupport
-    public boolean default2DownloadMetaModelXml() {
-        return true;
     }
 
-    // -- ASCII
 
-    public static class DownloadMetaModelAsciiEvent extends ActionDomainEvent { }
     @Action(
-            domainEvent = DownloadMetaModelAsciiEvent.class,
+            domainEvent = downloadMetaModelAscii.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -188,72 +176,62 @@ public class MetaModelServiceMenu {
             cssClassFa = "fa-download",
             named = "Download Meta Model (Ascii)",
             sequence="500.500.2")
-    public Blob downloadMetaModelAscii(
-            @ParameterLayout(named = ".txt file name")
-            final String fileName,
-
-            @ParameterLayout(named = "Namespaces",
-            describedAs="Subset of the complete meta model, only including namespaces starting with given prefix")
-            final List<String> namespaces,
-
-            @ParameterLayout(named = "Ignore Interfaces")
-            @Parameter(optionality=Optionality.MANDATORY)
-            final boolean ignoreInterfaces
-            ) {
-
-        Config config =
-                new Config()
-                .withIgnoreNoop()
-                .withIgnoreAbstractClasses()
-                .withIgnoreInterfaces()
-                .withIgnoreBuiltInValueTypes();
-        for (final String namespace : namespaces) {
-            config = config.withNamespacePrefix(namespace);
-        }
-        if(ignoreInterfaces) {
-            config = config.withIgnoreInterfaces();
-        }
-
-        final MetamodelDto metamodelDto =  metaModelService.exportMetaModel(config);
+    public class downloadMetaModelAscii{
+
+        public class ActionEvent extends ActionDomainEvent<downloadMetaModelAscii> { }
+
+        @MemberSupport public Blob act(
+                @ParameterLayout(named = ".txt file name")
+                final String fileName,
+
+                @ParameterLayout(named = "Namespaces",
+                        describedAs="Subset of the complete meta model, only including namespaces starting with given prefix")
+                final List<String> namespaces,
+
+                @ParameterLayout(named = "Ignore Interfaces")
+                @Parameter(optionality=Optionality.MANDATORY)
+                final boolean ignoreInterfaces
+        ) {
+
+            Config config =
+                    new Config()
+                            .withIgnoreNoop()
+                            .withIgnoreAbstractClasses()
+                            .withIgnoreInterfaces()
+                            .withIgnoreBuiltInValueTypes();
+            for (final String namespace : namespaces) {
+                config = config.withNamespacePrefix(namespace);
+            }
+            if(ignoreInterfaces) {
+                config = config.withIgnoreInterfaces();
+            }
 
-        final StringBuilder ascii = _AsciiExport.toAscii(metamodelDto);
-        
-        return Clob.of(fileName, CommonMimeType.TXT, ascii)
-                .toBlob(UTF_8)
-                .zip();
+            final MetamodelDto metamodelDto =  metaModelService.exportMetaModel(config);
 
-        // ...
-    }
+            final StringBuilder ascii = _AsciiExport.toAscii(metamodelDto);
 
-    @MemberSupport
-    public String validateDownloadMetaModelAscii(
-            final String fileName, final List<String> namespacePrefixes, final boolean ignoreInterfaces) {
-        if(namespacePrefixes == null || namespacePrefixes.isEmpty()) {
-            return "At least one package must be selected";
+            return Clob.of(fileName, CommonMimeType.TXT, ascii)
+                    .toBlob(UTF_8)
+                    .zip();
         }
-        return null;
-    }
 
-    @MemberSupport
-    public String default0DownloadMetaModelAscii() {
-        return "metamodel.txt";
-    }
+        @MemberSupport public String validateAct(
+                final String fileName, final List<String> namespacePrefixes, final boolean ignoreInterfaces) {
+            if(namespacePrefixes == null || namespacePrefixes.isEmpty()) {
+                return "At least one package must be selected";
+            }
+            return null;
+        }
 
-    @MemberSupport
-    public List<String> choices1DownloadMetaModelAscii() {
-        return namespaceChoices();
-    }
+        @MemberSupport public String default0Act() { return "metamodel.txt"; }
+        @MemberSupport public List<String> choices1Act() { return namespaceChoices(); }
+        @MemberSupport public boolean default2Act() { return true; }
 
-    @MemberSupport
-    public boolean default2DownloadMetaModelAscii() {
-        return true;
     }
 
-    // -- DIFF
 
-    public static class DownloadMetaModelDiffEvent extends ActionDomainEvent { }
     @Action(
-            domainEvent = DownloadMetaModelDiffEvent.class,
+            domainEvent = downloadMetaModelDiff.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -261,83 +239,76 @@ public class MetaModelServiceMenu {
             cssClassFa = "fa-download",
             named = "Generate Meta Model Diff",
             sequence="500.500.2")
-    public Blob downloadMetaModelDiff(
-            @ParameterLayout(named = ".txt file name")
-            final String fileName,
-
-            @ParameterLayout(named = "Namespaces",
-            describedAs="Subset of the complete meta model, only including namespaces starting with given prefix")
-            final List<String> namespaces,
-
-            @ParameterLayout(named = "Ignore Interfaces")
-            @Parameter(optionality=Optionality.MANDATORY)
-            final boolean ignoreInterfaces, 
-            
-            @ParameterLayout(named="Metamodel (Zipped XML)", 
-            describedAs="Metamodel from a previous export, to compare the current with.")
-            @Parameter(fileAccept=".zip", optionality = Optionality.MANDATORY)
-            Blob zippedMetamodelBlob
-            
-            ) throws IOException {
-
-        Config config =
-                new Config()
-                .withIgnoreNoop()
-                .withIgnoreAbstractClasses()
-                .withIgnoreInterfaces()
-                .withIgnoreBuiltInValueTypes();
-        for (final String namespace : namespaces) {
-            config = config.withNamespacePrefix(namespace);
-        }
-        if(ignoreInterfaces) {
-            config = config.withIgnoreInterfaces();
-        }
+    public class downloadMetaModelDiff {
 
-        final MetamodelDto leftMetamodelDto =  metaModelService.exportMetaModel(config);
+        public class ActionEvent extends ActionDomainEvent<downloadMetaModelDiff> { }
 
-        final String xml = zippedMetamodelBlob
-                .unZip(CommonMimeType.XML)
-                .toClob(UTF_8)
-                .getChars()
-                .toString();
-        
-        final MetamodelDto rightMetamodelDto =  jaxbService.fromXml(MetamodelDto.class, xml);
+        @MemberSupport public Blob act(
+                @ParameterLayout(named = ".txt file name")
+                final String fileName,
 
-        final StringBuilder diff = _DiffExport.toDiff(leftMetamodelDto, rightMetamodelDto);
+                @ParameterLayout(named = "Namespaces",
+                        describedAs="Subset of the complete meta model, only including namespaces starting with given prefix")
+                final List<String> namespaces,
 
-        return Clob.of(fileName, CommonMimeType.TXT, diff)
-                .toBlob(UTF_8)
-                .zip();
+                @ParameterLayout(named = "Ignore Interfaces")
+                @Parameter(optionality=Optionality.MANDATORY)
+                final boolean ignoreInterfaces,
 
-        // ...
-    }
+                @ParameterLayout(named="Metamodel (Zipped XML)",
+                        describedAs="Metamodel from a previous export, to compare the current with.")
+                @Parameter(fileAccept=".zip", optionality = Optionality.MANDATORY)
+                        Blob zippedMetamodelBlob
 
-    
-    @MemberSupport
-    public String validateDownloadMetaModelDiff(
-            final String fileName, 
-            final List<String> namespacePrefixes, 
-            final boolean ignoreInterfaces,
-            final Blob rightMetamodelBlob) {
-        if(namespacePrefixes == null || namespacePrefixes.isEmpty()) {
-            return "At least one package must be selected";
+        ) throws IOException {
+
+            Config config =
+                    new Config()
+                            .withIgnoreNoop()
+                            .withIgnoreAbstractClasses()
+                            .withIgnoreInterfaces()
+                            .withIgnoreBuiltInValueTypes();
+            for (final String namespace : namespaces) {
+                config = config.withNamespacePrefix(namespace);
+            }
+            if(ignoreInterfaces) {
+                config = config.withIgnoreInterfaces();
+            }
+
+            final MetamodelDto leftMetamodelDto =  metaModelService.exportMetaModel(config);
+
+            final String xml = zippedMetamodelBlob
+                    .unZip(CommonMimeType.XML)
+                    .toClob(UTF_8)
+                    .getChars()
+                    .toString();
+
+            final MetamodelDto rightMetamodelDto =  jaxbService.fromXml(MetamodelDto.class, xml);
+
+            final StringBuilder diff = _DiffExport.toDiff(leftMetamodelDto, rightMetamodelDto);
+
+            return Clob.of(fileName, CommonMimeType.TXT, diff)
+                    .toBlob(UTF_8)
+                    .zip();
+
+            // ...
         }
-        return null;
-    }
 
-    @MemberSupport
-    public String default0DownloadMetaModelDiff() {
-        return "metamodel-diff.txt";
-    }
+        @MemberSupport public String validateAct(
+                final String fileName,
+                final List<String> namespacePrefixes,
+                final boolean ignoreInterfaces,
+                final Blob rightMetamodelBlob) {
+            if(namespacePrefixes == null || namespacePrefixes.isEmpty()) {
+                return "At least one package must be selected";
+            }
+            return null;
+        }
 
-    @MemberSupport
-    public List<String> choices1DownloadMetaModelDiff() {
-        return namespaceChoices();
-    }
+        @MemberSupport public String default0Act() { return "metamodel-diff.txt"; }
+        @MemberSupport public List<String> choices1Act() { return namespaceChoices(); }
+        @MemberSupport public boolean default2Act() { return true; }
 
-    @MemberSupport
-    public boolean default2DownloadMetaModelDiff() {
-        return true;
     }
 
     
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateMenu.java
index d4c69f0..c09844c 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateMenu.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateMenu.java
@@ -69,102 +69,106 @@ public class ImpersonateMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE_SUDO + ".ImpersonateMenu";   // deliberately not part of isis.applib
 
+    public static abstract class ActionDomainEvent<T> extends IsisModuleApplib.ActionDomainEvent<T> {}
+
+
     final UserService userService;
     final MessageService messageService;
     final List<ImpersonateMenuAdvisor> impersonateMenuAdvisors;
 
 
 
-    public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<ImpersonateMenu> {}
-
-
-
-    public static class ImpersonateDomainEvent extends ActionDomainEvent { }
-
-    /**
-     * Simple implementation that is surfaced if there is no advisor.
-     *
-     * @param userName
-     */
     @Action(
-            domainEvent = ImpersonateDomainEvent.class,
+            domainEvent = impersonate.ActionEvent.class,
             semantics = SemanticsOf.IDEMPOTENT,
             commandPublishing = Publishing.DISABLED,
             executionPublishing = Publishing.DISABLED,
             restrictTo = RestrictTo.PROTOTYPING
     )
     @ActionLayout(sequence = "100.1", cssClassFa = "fa-mask")
-    public void impersonate(
-            final String userName) {
-
-        // TODO: should use an SPI for each configured viewer to add in its own role if necessary.
-        this.userService.impersonateUser(userName, Collections.singletonList("org.apache.isis.viewer.wicket.roles.USER"), null);
-        this.messageService.informUser("Now impersonating " + userName);
-    }
-    @MemberSupport public boolean hideImpersonate() {
-        return ! this.userService.supportsImpersonation() || !hideImpersonateWithRoles();
-    }
-    @MemberSupport public String disableImpersonate() {
-        return this.userService.isImpersonating() ? "currently impersonating" : null;
-    }
+    public class impersonate {
 
+        public class ActionEvent extends ActionDomainEvent<impersonate.ActionEvent> { }
 
+        /**
+         * Simple implementation that is surfaced if there is no advisor.
+         *
+         * @param userName
+         */
+        @MemberSupport public void act(
+                final String userName) {
 
+            // TODO: should use an SPI for each configured viewer to add in its own role if necessary.
+            userService.impersonateUser(userName, Collections.singletonList("org.apache.isis.viewer.wicket.roles.USER"), null);
+            messageService.informUser("Now impersonating " + userName);
+        }
+        @MemberSupport public boolean hideAct() {
+            return ! userService.supportsImpersonation() || !hideAct();
+        }
+        @MemberSupport public String disableAct() {
+            return userService.isImpersonating() ? "currently impersonating" : null;
+        }
 
+    }
 
-    public static class ImpersonateWithRolesDomainEvent extends ActionDomainEvent { }
 
-    /**
-     * Impersonate a selected user, either using their current roles or
-     * with a specific set of roles.
-     *
-     * <p>
-     * This more sophisticated implementation is only available if there is
-     * an {@link ImpersonateMenuAdvisor} implementation to provide the
-     * choices.
-     * </p>
-     *  @param userName
-     * @param roleNames
-     * @param multiTenancyToken
-     */
     @Action(
-            domainEvent = ImpersonateWithRolesDomainEvent.class,
+            domainEvent = impersonateWithRoles.ActionEvent.class,
             semantics = SemanticsOf.IDEMPOTENT,
             commandPublishing = Publishing.DISABLED,
             executionPublishing = Publishing.DISABLED,
             restrictTo = RestrictTo.PROTOTYPING
     )
     @ActionLayout(sequence = "100.2", cssClassFa = "fa-mask")
-    public void impersonateWithRoles(
-            final String userName,
-            final List<String> roleNames,
-            final String multiTenancyToken) {
-
-        // TODO: should use an SPI for each configured viewer to add in its own role if necessary.
-        val roleNamesCopy = new ArrayList<>(roleNames);
-        if(!roleNamesCopy.contains("org.apache.isis.viewer.wicket.roles.USER")) {
-            roleNamesCopy.add("org.apache.isis.viewer.wicket.roles.USER");
+    public class impersonateWithRoles {
+
+        public class ActionEvent extends ActionDomainEvent<impersonateWithRoles> { }
+
+        /**
+         * Impersonate a selected user, either using their current roles or
+         * with a specific set of roles.
+         *
+         * <p>
+         * This more sophisticated implementation is only available if there is
+         * an {@link ImpersonateMenuAdvisor} implementation to provide the
+         * choices.
+         * </p>
+         *
+         * @param userName - user name
+         * @param roleNames - role names
+         * @param multiTenancyToken - multi-tenancy token
+         */
+        @MemberSupport public void act(
+                final String userName,
+                final List<String> roleNames,
+                final String multiTenancyToken) {
+
+            // TODO: should use an SPI for each configured viewer to add in its own role if necessary.
+            val roleNamesCopy = new ArrayList<>(roleNames);
+            if(!roleNamesCopy.contains("org.apache.isis.viewer.wicket.roles.USER")) {
+                roleNamesCopy.add("org.apache.isis.viewer.wicket.roles.USER");
+            }
+            userService.impersonateUser(userName, roleNamesCopy, multiTenancyToken);
+            messageService.informUser("Now impersonating " + userName);
+        }
+        @MemberSupport public boolean hideAct() {
+            return ! userService.supportsImpersonation() || choices0Act().isEmpty();
+        }
+        @MemberSupport public String disableAct() {
+            return userService.isImpersonating() ? "currently impersonating" : null;
+        }
+        @MemberSupport public List<String> choices0Act() {
+            return impersonateMenuAdvisor().allUserNames();
+        }
+        @MemberSupport public List<String> choices1Act(final String userName) {
+            return impersonateMenuAdvisor().allRoleNames();
+        }
+        @MemberSupport public List<String> default1Act(final String userName) {
+            return impersonateMenuAdvisor().roleNamesFor(userName);
+        }
+        @MemberSupport public String default2Act(final String userName, final List<String> roleNames) {
+            return impersonateMenuAdvisor().multiTenancyTokenFor(userName);
         }
-        this.userService.impersonateUser(userName, roleNamesCopy, multiTenancyToken);
-        this.messageService.informUser("Now impersonating " + userName);
-    }
-    @MemberSupport public boolean hideImpersonateWithRoles() {
-        return ! this.userService.supportsImpersonation() || choices0ImpersonateWithRoles().isEmpty();
-    }
-    @MemberSupport public String disableImpersonateWithRoles() {
-        return this.userService.isImpersonating() ? "currently impersonating" : null;
-    }
-    @MemberSupport public List<String> choices0ImpersonateWithRoles() {
-        return impersonateMenuAdvisor().allUserNames();
-    }
-    @MemberSupport public List<String> choices1ImpersonateWithRoles(final String userName) {
-        return impersonateMenuAdvisor().allRoleNames();
-    }
-    @MemberSupport public List<String> default1ImpersonateWithRoles(final String userName) {
-        return impersonateMenuAdvisor().roleNamesFor(userName);
-    }
-    @MemberSupport public String default2ImpersonateWithRoles(final String userName, final List<String> roleNames) {
-        return impersonateMenuAdvisor().multiTenancyTokenFor(userName);
     }
 
     private ImpersonateMenuAdvisor impersonateMenuAdvisor() {
@@ -172,5 +176,4 @@ public class ImpersonateMenu {
         return impersonateMenuAdvisors.get(0);
     }
 
-
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateStopMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateStopMenu.java
index 3aa69e0..6233f14 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateStopMenu.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/ImpersonateStopMenu.java
@@ -69,26 +69,28 @@ public class ImpersonateStopMenu {
     final MessageService messageService;
 
 
-    public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<ImpersonateStopMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleApplib.ActionDomainEvent<T> {}
 
 
-    public static class StopImpersonatingDomainEvent extends ActionDomainEvent { }
-
     @Action(
-            domainEvent = ImpersonateStopMenu.StopImpersonatingDomainEvent.class,
+            domainEvent = stopImpersonating.ActionEvent.class,
             semantics = SemanticsOf.IDEMPOTENT,
             commandPublishing = Publishing.DISABLED,
             executionPublishing = Publishing.DISABLED,
             restrictTo = RestrictTo.PROTOTYPING
     )
     @ActionLayout(sequence = "100.3", redirectPolicy = Redirect.EVEN_IF_SAME)
-    public void stopImpersonating() {
-        this.userService.stopImpersonating();
-        this.messageService.informUser("No longer impersonating another user");
-    }
-    @MemberSupport
-    public boolean hideStopImpersonating() {
-        return ! isImpersonating();
+    public class stopImpersonating{
+
+        public class ActionEvent extends ActionDomainEvent<stopImpersonating> { }
+
+        @MemberSupport public void act() {
+            userService.stopImpersonating();
+            messageService.informUser("No longer impersonating another user");
+        }
+        @MemberSupport public boolean hideAct() {
+            return ! isImpersonating();
+        }
     }
 
     private boolean isImpersonating() {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java
index 8727cc1..3c3ae10 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java
@@ -50,15 +50,13 @@ public class UserMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE + ".UserMenu";
 
-    public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<UserMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleApplib.ActionDomainEvent<T> {}
 
     final UserService userService;
 
 
-    public static class MeDomainEvent extends ActionDomainEvent {}
-
     @Action(
-            domainEvent = MeDomainEvent.class,
+            domainEvent = me.ActionEvent.class,
             semantics = SemanticsOf.SAFE
             )
     @ActionLayout(
@@ -66,13 +64,15 @@ public class UserMenu {
             describedAs = "Returns your user account details",
             sequence = "100"
         )
-    public UserMemento me() {
-        return userService.currentUser().orElse(null);
-    }
-    @MemberSupport
-    public String disableMe() {
-        return userService.currentUser().isPresent() ? null : "Current user not available";
-    }
+    public class me {
 
+        public class ActionEvent extends ActionDomainEvent<me> {}
+
+        @MemberSupport public UserMemento act() { return userService.currentUser().orElse(null); }
+        @MemberSupport public String disableAct() {
+            return userService.currentUser().isPresent() ? null : "Current user not available";
+        }
+
+    }
 
 }
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/Object_openOnSecondary.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/Object_openOnSecondary.java
index 61c6e3e..94295ef 100644
--- a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/Object_openOnSecondary.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/mixins/Object_openOnSecondary.java
@@ -25,6 +25,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Publishing;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
@@ -61,7 +62,10 @@ public class Object_openOnSecondary {
 
     final Object object;
 
-    public URL act() {
+    @Inject PrimaryConfig primaryConfig;
+    @Inject BookmarkService bookmarkService;
+
+    @MemberSupport public URL act() {
         val baseUrlPrefix = lookupBaseUrlPrefix();
         val urlSuffix = bookmarkService.bookmarkForElseFail(object).toString();
 
@@ -71,7 +75,8 @@ public class Object_openOnSecondary {
             throw new RecoverableException(e);
         }
     }
-    public boolean hideAct() {
+
+    @MemberSupport public boolean hideAct() {
         return !primaryConfig.isConfigured();
     }
 
@@ -79,7 +84,5 @@ public class Object_openOnSecondary {
         return primaryConfig.getSecondaryBaseUrlWicket() + "entity/";
     }
 
-    @Inject PrimaryConfig primaryConfig;
-    @Inject BookmarkService bookmarkService;
 
 }
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
index ada96b6..fb56ee0 100644
--- a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
@@ -21,12 +21,20 @@ package org.apache.isis.extensions.commandreplay.primary.ui;
 import java.util.List;
 import java.util.UUID;
 
-import org.springframework.lang.Nullable;
 import javax.inject.Inject;
 import javax.inject.Named;
 
-import org.apache.isis.applib.annotation.*;
+import org.springframework.lang.Nullable;
+
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.exceptions.RecoverableException;
 import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
 import org.apache.isis.applib.services.jaxb.JaxbService;
@@ -67,11 +75,9 @@ public class CommandReplayOnPrimaryService {
     @Inject final ContentMappingServiceForCommandsDto contentMappingServiceForCommandsDto;
     @Inject final CommandRetrievalService commandRetrievalService;
 
-    public static abstract class ActionDomainEvent
-            extends IsisModuleExtCommandReplayPrimary.ActionDomainEvent<CommandReplayOnPrimaryService> { }
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtCommandReplayPrimary.ActionDomainEvent<T> { }
 
 
-    public static class FindCommandsDomainEvent extends ActionDomainEvent { }
     public static class NotFoundException extends RecoverableException {
         private static final long serialVersionUID = 1L;
         @Getter
@@ -82,106 +88,122 @@ public class CommandReplayOnPrimaryService {
         }
     }
 
-    /**
-     * These actions should be called with HTTP Accept Header set to:
-     * <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"</code>
-     *
-     * @param interactionId - to search from.  This transactionId will <i>not</i> be included in the response.
-     * @param batchSize - the maximum number of commands to return.  If not specified, all found will be returned.
-     * @throws NotFoundException - if the command with specified transaction cannot be found.
-     */
-    @Action(domainEvent = FindCommandsDomainEvent.class, semantics = SemanticsOf.SAFE)
+    @Action(domainEvent = findCommands.ActionEvent.class, semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa = "fa-search", sequence="40")
-    public List<? extends CommandModel> findCommands(
-            @Nullable
-            @ParameterLayout(named="Interaction Id")
-            final UUID interactionId,
-            @Nullable
-            @ParameterLayout(named="Batch size")
-            final Integer batchSize)
-            throws NotFoundException {
-        return commandRetrievalService.findCommandsOnPrimaryFrom(interactionId, batchSize);
-    }
-    @MemberSupport public Integer default1FindCommandsOnPrimaryFrom() {
-        return commandRetrievalService.default1FindCommandsOnPrimaryFrom();
+    public class findCommands{
+
+        public class ActionEvent extends ActionDomainEvent<findCommands> { }
+
+        /**
+         * These actions should be called with HTTP Accept Header set to:
+         * <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"</code>
+         *
+         * @param interactionId - to search from.  This transactionId will <i>not</i> be included in the response.
+         * @param batchSize - the maximum number of commands to return.  If not specified, all found will be returned.
+         * @throws NotFoundException - if the command with specified transaction cannot be found.
+         */
+        @MemberSupport public List<? extends CommandModel> act(
+                @Nullable
+                @ParameterLayout(named="Interaction Id")
+                final UUID interactionId,
+                @Nullable
+                @ParameterLayout(named="Batch size")
+                final Integer batchSize)
+                throws NotFoundException {
+            return commandRetrievalService.findCommandsOnPrimaryFrom(interactionId, batchSize);
+        }
+        @MemberSupport public Integer default1Act() {
+            return commandRetrievalService.default1FindCommandsOnPrimaryFrom();
+        }
+
     }
 
 
 
-    public static class DownloadCommandsDomainEvent extends ActionDomainEvent { }
-    /**
-     * These actions should be called with HTTP Accept Header set to:
-     * <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"</code>
-     *
-     * @param interactionId - to search from.  This transactionId will <i>not</i> be included in the response.
-     * @param batchSize - the maximum number of commands to return.  If not specified, all found will be returned.
-     * @throws NotFoundException - if the command with specified transaction cannot be found.
-     */
-    @Action(domainEvent = DownloadCommandsDomainEvent.class, semantics = SemanticsOf.SAFE)
+
+    @Action(domainEvent = downloadCommands.ActionEvent.class, semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa = "fa-download", sequence="50")
-    public Clob downloadCommands(
-            @Nullable
-            final UUID interactionId,
-            @Nullable
-            final Integer batchSize,
-            final String filenamePrefix) {
-        final List<? extends CommandModel> commands = commandModelRepository.findSince(interactionId, batchSize);
-        if(commands == null) {
-            messageService.informUser("No commands found");
+    public class downloadCommands {
+
+        public class ActionEvent extends ActionDomainEvent<downloadCommands> { }
+
+        /**
+         * These actions should be called with HTTP Accept Header set to:
+         * <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandsDto"</code>
+         *
+         * @param interactionId - to search from.  This transactionId will <i>not</i> be included in the response.
+         * @param batchSize - the maximum number of commands to return.  If not specified, all found will be returned.
+         * @throws NotFoundException - if the command with specified transaction cannot be found.
+         */
+        @MemberSupport public Clob act(
+                @Nullable
+                final UUID interactionId,
+                @Nullable
+                final Integer batchSize,
+                final String filenamePrefix) {
+            final List<? extends CommandModel> commands = commandModelRepository.findSince(interactionId, batchSize);
+            if(commands == null) {
+                messageService.informUser("No commands found");
+            }
+
+            final CommandsDto commandsDto =
+                    contentMappingServiceForCommandsDto.map(commands);
+
+            final String fileName = String.format(
+                    "%s_%s.xml", filenamePrefix, elseDefault(interactionId));
+
+            final String xml = jaxbService.toXml(commandsDto);
+            return new Clob(fileName, "application/xml", xml);
+        }
+        @MemberSupport public Integer default1Act() {
+            return 25;
+        }
+        @MemberSupport public String default2Act() {
+            return "commands_from";
         }
 
-        final CommandsDto commandsDto =
-                contentMappingServiceForCommandsDto.map(commands);
-
-        final String fileName = String.format(
-                "%s_%s.xml", filenamePrefix, elseDefault(interactionId));
-
-        final String xml = jaxbService.toXml(commandsDto);
-        return new Clob(fileName, "application/xml", xml);
-    }
-    @MemberSupport public Integer default1DownloadCommands() {
-        return 25;
-    }
-    @MemberSupport public String default2DownloadCommands() {
-        return "commands_from";
     }
 
 
 
-    public static class DownloadCommandByIdDomainEvent extends ActionDomainEvent { }
-    /**
-     * This action should be called with HTTP Accept Header set to:
-     * <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandDto"</code>
-     *
-     * @param interactionId - to download.
-     * @throws NotFoundException - if the command with specified transaction cannot be found.
-     */
-    @Action(domainEvent = DownloadCommandByIdDomainEvent.class, semantics = SemanticsOf.SAFE)
+    @Action(domainEvent = downloadCommandById.ActionEvent.class, semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa = "fa-download", sequence="50")
-    public Clob downloadCommandById(
-            final UUID interactionId,
-            final String filenamePrefix) {
+    public class downloadCommandById {
 
-        return commandModelRepository.findByInteractionId(interactionId)
-                .map(commandJdo -> {
+        public class ActionEvent extends ActionDomainEvent<downloadCommandById> { }
 
-                    final CommandDto commandDto = commandJdo.getCommandDto();
+        /**
+         * This action should be called with HTTP Accept Header set to:
+         * <code>application/xml;profile="urn:org.restfulobjects:repr-types/action-result";x-ro-domain-type="org.apache.isis.schema.cmd.v1.CommandDto"</code>
+         *
+         * @param interactionId - to download.
+         * @throws NotFoundException - if the command with specified transaction cannot be found.
+         */
+        @MemberSupport public Clob act(
+                final UUID interactionId,
+                final String filenamePrefix) {
 
-                    final String fileName = String.format(
-                            "%s_%s.xml", filenamePrefix, elseDefault(interactionId));
+            return commandModelRepository.findByInteractionId(interactionId)
+                    .map(commandJdo -> {
 
-                    final String xml = jaxbService.toXml(commandDto);
-                    return new Clob(fileName, "application/xml", xml);
+                        final CommandDto commandDto = commandJdo.getCommandDto();
 
-                }).orElseGet(() -> {
-                    messageService.informUser("No command found");
-                    return null;
-                });
-    }
-    @MemberSupport public String default1DownloadCommandById() {
-        return "command";
-    }
+                        final String fileName = String.format(
+                                "%s_%s.xml", filenamePrefix, elseDefault(interactionId));
 
+                        final String xml = jaxbService.toXml(commandDto);
+                        return new Clob(fileName, "application/xml", xml);
+
+                    }).orElseGet(() -> {
+                        messageService.informUser("No command found");
+                        return null;
+                    });
+        }
+        @MemberSupport public String default1Act() {
+            return "command";
+        }
+
+    }
 
     private static String elseDefault(final UUID uuid) {
         return uuid != null ? uuid.toString() : "00000000-0000-0000-0000-000000000000";
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
index fecbc10..6c3bf0a 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
@@ -59,41 +59,48 @@ public class CommandReplayOnSecondaryService {
     @Inject CommandModelRepository<? extends CommandModel> commandModelRepository;
     @Inject final JaxbService jaxbService;
 
-    public static abstract class ActionDomainEvent
-            extends IsisModuleExtCommandReplaySecondary.ActionDomainEvent<CommandReplayOnSecondaryService> { }
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtCommandReplaySecondary.ActionDomainEvent<T> { }
 
-    public static class FindMostRecentReplayedDomainEvent extends ActionDomainEvent { }
-    @Action(domainEvent = FindMostRecentReplayedDomainEvent.class, semantics = SemanticsOf.SAFE)
+    @Action(domainEvent = findMostRecentReplayed.ActionEvent.class, semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa = "fa-bath", sequence="60.1")
-    public CommandModel findMostRecentReplayed() {
-        return commandModelRepository.findMostRecentReplayed().orElse(null);
+    public class findMostRecentReplayed{
+
+        public class ActionEvent extends ActionDomainEvent<findMostRecentReplayed> { }
+
+        @MemberSupport public CommandModel act() {
+            return commandModelRepository.findMostRecentReplayed().orElse(null);
+        }
     }
 
-    public static class UploadCommandsDomainEvent extends ActionDomainEvent { }
+
     @Action(
-        domainEvent = UploadCommandsDomainEvent.class,
+        domainEvent = uploadCommands.ActionEvent.class,
         semantics = SemanticsOf.NON_IDEMPOTENT
     )
     @ActionLayout(cssClassFa = "fa-upload", sequence="60.2")
-    public void uploadCommands(final Clob commandsDtoAsXml) {
-        val chars = commandsDtoAsXml.getChars();
-        List<CommandDto> commandDtoList;
+    public class uploadCommands{
 
-        try {
-            val commandsDto = jaxbService.fromXml(CommandsDto.class, chars.toString());
-            commandDtoList = commandsDto.getCommandDto();
+        public class ActionEvent extends ActionDomainEvent<uploadCommands> { }
 
-        } catch(Exception ex) {
-            val commandDto = jaxbService.fromXml(CommandDto.class, chars.toString());
-            commandDtoList = Collections.singletonList(commandDto);
-        }
+        @MemberSupport public void act(final Clob commandsDtoAsXml) {
+            val chars = commandsDtoAsXml.getChars();
+            List<CommandDto> commandDtoList;
 
-        for (final CommandDto commandDto : commandDtoList) {
-            commandModelRepository.saveForReplay(commandDto);
-        }
-    }
+            try {
+                val commandsDto = jaxbService.fromXml(CommandsDto.class, chars.toString());
+                commandDtoList = commandsDto.getCommandDto();
 
+            } catch(Exception ex) {
+                val commandDto = jaxbService.fromXml(CommandDto.class, chars.toString());
+                commandDtoList = Collections.singletonList(commandDto);
+            }
 
+            for (final CommandDto commandDto : commandDtoList) {
+                commandModelRepository.saveForReplay(commandDto);
+            }
+        }
+
+    }
 
 }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/app/mixins/ApplicationOrphanedPermissionManager_relocateSelected.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/app/mixins/ApplicationOrphanedPermissionManager_relocateSelected.java
index d199477..a45c540 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/app/mixins/ApplicationOrphanedPermissionManager_relocateSelected.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/app/mixins/ApplicationOrphanedPermissionManager_relocateSelected.java
@@ -26,6 +26,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.SemanticsOf;
@@ -59,7 +60,7 @@ public class ApplicationOrphanedPermissionManager_relocateSelected {
 
     private final ApplicationOrphanedPermissionManager target;
 
-    public ApplicationOrphanedPermissionManager act(
+    @MemberSupport public ApplicationOrphanedPermissionManager act(
             final Collection<ApplicationPermission> permissions,
             @Parameter(optionality = Optionality.MANDATORY)
             final String targetNamespace) {
@@ -68,7 +69,7 @@ public class ApplicationOrphanedPermissionManager_relocateSelected {
         return target;
     }
 
-    public Collection<String> choices1Act() {
+    @MemberSupport public Collection<String> choices1Act() {
         return featureRepository.allNamespaces().stream()
                     .map(ApplicationFeature::getFullyQualifiedName)
                     .collect(Collectors.toCollection(TreeSet::new));
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_allow.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_allow.java
index 908e57b..565e206 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_allow.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_allow.java
@@ -20,6 +20,7 @@ package org.apache.isis.extensions.secman.applib.permission.dom.mixins;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
 import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermission;
@@ -44,12 +45,12 @@ public class ApplicationPermission_allow {
 
     private final ApplicationPermission target;
 
-    public ApplicationPermission act() {
+    @MemberSupport public ApplicationPermission act() {
         target.setRule(ApplicationPermissionRule.ALLOW);
         return target;
     }
 
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return target.getRule() == ApplicationPermissionRule.ALLOW? "Rule is already set to ALLOW": null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_changing.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_changing.java
index 0741536..7682935 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_changing.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_changing.java
@@ -20,6 +20,7 @@ package org.apache.isis.extensions.secman.applib.permission.dom.mixins;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
 import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermission;
@@ -44,12 +45,12 @@ public class ApplicationPermission_changing {
 
     private final ApplicationPermission target;
 
-    public ApplicationPermission act() {
+    @MemberSupport public ApplicationPermission act() {
         target.setMode(ApplicationPermissionMode.CHANGING);
         return target;
     }
 
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return target.getMode() == ApplicationPermissionMode.CHANGING ? "Mode is already set to CHANGING": null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_delete.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_delete.java
index e47a51b..77f3d38 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_delete.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_delete.java
@@ -22,6 +22,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
@@ -51,7 +52,7 @@ public class ApplicationPermission_delete {
 
     private final ApplicationPermission target;
 
-    public ApplicationRole act() {
+    @MemberSupport public ApplicationRole act() {
         val owningRole = target.getRole();
         repository.remove(target);
         return owningRole;
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_feature.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_feature.java
index 8aea7aa..bacd442 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_feature.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_feature.java
@@ -20,15 +20,15 @@ package org.apache.isis.extensions.secman.applib.permission.dom.mixins;
 
 import javax.inject.Inject;
 
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeatui.ApplicationFeatureViewModel;
 import org.apache.isis.applib.services.factory.FactoryService;
-import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
-import org.apache.isis.applib.services.appfeatui.ApplicationFeatureViewModel;
 import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermission;
 
 import lombok.RequiredArgsConstructor;
@@ -48,7 +48,10 @@ public class ApplicationPermission_feature {
 
     final ApplicationPermission target;
 
-    public ApplicationFeatureViewModel prop(final ApplicationPermission permission) {
+    @Inject FactoryService factory;
+    @Inject ApplicationFeatureRepository featureRepository;
+
+    @MemberSupport public ApplicationFeatureViewModel prop(final ApplicationPermission permission) {
         if(permission.getFeatureSort() == null) {
             return null;
         }
@@ -60,8 +63,5 @@ public class ApplicationPermission_feature {
         return ApplicationFeatureId.newFeature(permission.getFeatureSort(), permission.getFeatureFqn());
     }
 
-    @Inject RepositoryService repository;
-    @Inject FactoryService factory;
-    @Inject ApplicationFeatureRepository featureRepository;
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_updateRole.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_updateRole.java
index 09f11cb..3810bc2 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_updateRole.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_updateRole.java
@@ -54,19 +54,13 @@ public class ApplicationPermission_updateRole {
 
     private final ApplicationPermission target;
 
-    @MemberSupport
-    public ApplicationPermission act(final ApplicationRole applicationRole) {
+    @MemberSupport public ApplicationPermission act(final ApplicationRole applicationRole) {
         target.setRole(applicationRole);
         return target;
     }
 
-    @MemberSupport
-    public ApplicationRole default0Act() {
-        return target.getRole();
-    }
-
-    @MemberSupport
-    public Collection<? extends ApplicationRole> choices0Act() {
+    @MemberSupport public ApplicationRole default0Act() { return target.getRole(); }
+    @MemberSupport public Collection<? extends ApplicationRole> choices0Act() {
         return applicationRoleRepository.allRoles();
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_veto.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_veto.java
index 8c944a9..a9cf372 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_veto.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_veto.java
@@ -20,6 +20,7 @@ package org.apache.isis.extensions.secman.applib.permission.dom.mixins;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
 import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermission;
@@ -44,11 +45,12 @@ public class ApplicationPermission_veto {
 
     private final ApplicationPermission target;
 
-    public ApplicationPermission act() {
+    @MemberSupport public ApplicationPermission act() {
         target.setRule(ApplicationPermissionRule.VETO);
         return target;
     }
-    public String disableAct() {
+
+    @MemberSupport public String disableAct() {
         return target.getRule() == ApplicationPermissionRule.VETO? "Rule is already set to VETO": null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_viewing.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_viewing.java
index ea4c2ec..579ddbf 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_viewing.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/dom/mixins/ApplicationPermission_viewing.java
@@ -20,6 +20,7 @@ package org.apache.isis.extensions.secman.applib.permission.dom.mixins;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
 import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermission;
@@ -44,12 +45,12 @@ public class ApplicationPermission_viewing {
 
     private final ApplicationPermission target;
 
-    public ApplicationPermission act() {
+    @MemberSupport public ApplicationPermission act() {
         target.setMode(ApplicationPermissionMode.VIEWING);
         return target;
     }
 
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return target.getMode() == ApplicationPermissionMode.VIEWING ? "Mode is already set to VIEWING": null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/menu/ApplicationPermissionMenu.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/menu/ApplicationPermissionMenu.java
index ec390f2..3b8a677 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/menu/ApplicationPermissionMenu.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/permission/menu/ApplicationPermissionMenu.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.ObjectSupport;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
@@ -50,45 +51,47 @@ public class ApplicationPermissionMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleExtSecmanApplib.NAMESPACE + ".ApplicationPermissionMenu";
 
-    // -- domain event classes
-    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApplib.PropertyDomainEvent<ApplicationPermissionMenu, T> {}
-    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApplib.CollectionDomainEvent<ApplicationPermissionMenu, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApplib.ActionDomainEvent<ApplicationPermissionMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtSecmanApplib.ActionDomainEvent<T> {}
 
     @Inject private ApplicationPermissionRepository applicationPermissionRepository;
     @Inject private FactoryService factoryService;
 
-    // -- iconName
-    @ObjectSupport
-    public String iconName() {
+
+    @ObjectSupport public String iconName() {
         return "applicationPermission";
     }
 
 
-    // -- findOrphanedPermissions (action)
-    public static class FindOrphanedPermissionsDomainEvent extends ActionDomainEvent {}
-
     @Action(
-            domainEvent=FindOrphanedPermissionsDomainEvent.class,
+            domainEvent= findOrphanedPermissions.ActionEvent.class,
             semantics = SemanticsOf.SAFE
             )
     @ActionLayout(sequence = "100.50.1")
-    public ApplicationOrphanedPermissionManager findOrphanedPermissions() {
-        return factoryService.viewModel(new ApplicationOrphanedPermissionManager());
+    public class findOrphanedPermissions{
+
+        public class ActionEvent extends ActionDomainEvent<findOrphanedPermissions> {}
+
+        @MemberSupport public ApplicationOrphanedPermissionManager act() {
+            return factoryService.viewModel(new ApplicationOrphanedPermissionManager());
+        }
     }
 
 
-    // -- allPermissions (action)
-    public static class AllPermissionsDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent=AllPermissionsDomainEvent.class,
+            domainEvent= allPermissions.ActionEvent.class,
             semantics = SemanticsOf.SAFE,
             restrictTo = RestrictTo.PROTOTYPING
             )
     @ActionLayout(sequence = "100.50.2")
-    public Collection<? extends ApplicationPermission> allPermissions() {
-        return applicationPermissionRepository.allPermissions();
+    public class allPermissions {
+
+        public class ActionEvent extends ActionDomainEvent<allPermissions> {}
+
+        @MemberSupport public Collection<? extends ApplicationPermission> act() {
+            return applicationPermissionRepository.allPermissions();
+        }
+
     }
 
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addPermission.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addPermission.java
index ffc00d6..477819c 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addPermission.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addPermission.java
@@ -85,18 +85,9 @@ public class ApplicationRole_addPermission {
         return target;
     }
 
-    @MemberSupport
-    public ApplicationPermissionRule defaultRule(Parameters params) {
-        return ApplicationPermissionRule.ALLOW;
-    }
-
-    @MemberSupport
-    public ApplicationPermissionMode defaultMode(Parameters params) {
-        return ApplicationPermissionMode.CHANGING;
-    }
-
-    @MemberSupport
-    public java.util.Collection<ApplicationFeatureChoices.AppFeat> autoCompleteFeature(
+    @MemberSupport public ApplicationPermissionRule defaultRule(Parameters params) { return ApplicationPermissionRule.ALLOW; }
+    @MemberSupport public ApplicationPermissionMode defaultMode(Parameters params) { return ApplicationPermissionMode.CHANGING; }
+    @MemberSupport public java.util.Collection<ApplicationFeatureChoices.AppFeat> autoCompleteFeature(
             final Parameters params,
             final @MinLength(3) String search) {
         return applicationFeatureChoices.autoCompleteFeature(search);
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addUser.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addUser.java
index 0e6049b..c9d97f0 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addUser.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_addUser.java
@@ -57,14 +57,12 @@ public class ApplicationRole_addUser {
 
     private final ApplicationRole target;
 
-    @MemberSupport
-    public ApplicationRole act(final ApplicationUser applicationUser) {
+    @MemberSupport public ApplicationRole act(final ApplicationUser applicationUser) {
         applicationRoleRepository.addRoleToUser(target, applicationUser);
         return target;
     }
 
-    @MemberSupport
-    public List<? extends ApplicationUser> autoComplete0Act(final String search) {
+    @MemberSupport public List<? extends ApplicationUser> autoComplete0Act(final String search) {
         final Collection<? extends ApplicationUser> matchingSearch = applicationUserRepository.find(search);
         final List<? extends ApplicationUser> list = _Lists.newArrayList(matchingSearch);
         list.removeAll(applicationUserRepository.findByRole(target));
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_delete.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_delete.java
index 4826f2b..b05da68 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_delete.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_delete.java
@@ -52,14 +52,12 @@ public class ApplicationRole_delete {
 
     private final ApplicationRole holder;
 
-    @MemberSupport
-    public Collection<ApplicationRole> act() {
+    @MemberSupport public Collection<ApplicationRole> act() {
         applicationRoleRepository.deleteRole(holder);
         return applicationRoleRepository.allRoles();
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return applicationRoleRepository.isAdminRole(holder) ? "Cannot delete the admin role" : null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removePermissions.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removePermissions.java
index f0bbb79..e7a8d36 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removePermissions.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removePermissions.java
@@ -64,8 +64,7 @@ public class ApplicationRole_removePermissions {
 
     private final ApplicationRole target;
 
-    @MemberSupport
-    public ApplicationRole act(Collection<ApplicationPermission> permissions) {
+    @MemberSupport public ApplicationRole act(Collection<ApplicationPermission> permissions) {
 
         _NullSafe.stream(permissions)
         .filter(this::canRemove)
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removeUsers.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removeUsers.java
index 7714491..014541f 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removeUsers.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_removeUsers.java
@@ -24,6 +24,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.Domain;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.message.MessageService;
@@ -59,8 +60,7 @@ public class ApplicationRole_removeUsers {
 
     private final ApplicationRole target;
 
-    @MemberSupport
-    public ApplicationRole act(Collection<ApplicationUser> users) {
+    @MemberSupport public ApplicationRole act(Collection<ApplicationUser> users) {
 
         _NullSafe.stream(users)
         .filter(this::canRemove)
@@ -69,7 +69,8 @@ public class ApplicationRole_removeUsers {
         return target;
     }
 
-    public boolean canRemove(ApplicationUser applicationUser) {
+    @Domain.Exclude
+    boolean canRemove(ApplicationUser applicationUser) {
         if(applicationUserRepository.isAdminUser(applicationUser)
                 && applicationRoleRepository.isAdminRole(target)) {
             messageService.warnUser("Cannot remove admin user from the admin role.");
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateDescription.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateDescription.java
index 8c740a5..67c925a 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateDescription.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateDescription.java
@@ -46,8 +46,7 @@ public class ApplicationRole_updateDescription {
 
     private final ApplicationRole target;
 
-    @MemberSupport
-    public ApplicationRole act(
+    @MemberSupport public ApplicationRole act(
             @ApplicationRole.Description
             final String description) {
 
@@ -55,10 +54,7 @@ public class ApplicationRole_updateDescription {
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
-        return target.getDescription();
-    }
+    @MemberSupport public String default0Act() { return target.getDescription(); }
 
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateName.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateName.java
index dac7af0..2dae1ac 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateName.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/dom/mixins/ApplicationRole_updateName.java
@@ -46,8 +46,7 @@ public class ApplicationRole_updateName {
 
     private final ApplicationRole target;
 
-    @MemberSupport
-    public ApplicationRole act(
+    @MemberSupport public ApplicationRole act(
             @ApplicationRole.Name
             final String name) {
 
@@ -55,9 +54,6 @@ public class ApplicationRole_updateName {
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
-        return target.getName();
-    }
+    @MemberSupport public String default0Act() { return target.getName(); }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/menu/ApplicationRoleMenu.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/menu/ApplicationRoleMenu.java
index b752182..18af54c 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/menu/ApplicationRoleMenu.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/role/menu/ApplicationRoleMenu.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.ObjectSupport;
 import org.apache.isis.applib.annotation.Optionality;
@@ -53,66 +54,71 @@ public class ApplicationRoleMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleExtSecmanApplib.NAMESPACE + ".ApplicationRoleMenu";
 
-    // -- domain event classes
-    public static class PropertyDomainEvent<T> extends IsisModuleExtSecmanApplib.PropertyDomainEvent<ApplicationRoleMenu, T> {}
-    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApplib.CollectionDomainEvent<ApplicationRoleMenu, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApplib.ActionDomainEvent<ApplicationRoleMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtSecmanApplib.ActionDomainEvent<T> {}
 
     private final ApplicationRoleRepository applicationRoleRepository;
 
 
-    // -- iconName
-    @ObjectSupport
-    public String iconName() {
+    @ObjectSupport public String iconName() {
         return "applicationRole";
     }
 
 
-    // -- findRoles
-    public static class FindRolesDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = FindRolesDomainEvent.class,
+            domainEvent = findRoles.ActionEvent.class,
             semantics = SemanticsOf.SAFE
             )
     @ActionLayout(sequence = "100.20.1")
-    public Collection<? extends ApplicationRole> findRoles(
-            @Parameter(maxLength = ApplicationRole.Name.MAX_LENGTH)
-            @ParameterLayout(named = "Search", typicalLength = ApplicationRole.Name.TYPICAL_LENGTH)
-            final String search) {
-        return applicationRoleRepository.findNameContaining(search);
-    }
+    public class findRoles {
+
+        public class ActionEvent extends ActionDomainEvent<findRoles> {}
 
+        @MemberSupport public Collection<? extends ApplicationRole> act(
+                @Parameter(maxLength = ApplicationRole.Name.MAX_LENGTH)
+                @ParameterLayout(named = "Search", typicalLength = ApplicationRole.Name.TYPICAL_LENGTH)
+                final String search) {
+            return applicationRoleRepository.findNameContaining(search);
+        }
+
+    }
 
-    // -- newRole
-    public static class NewRoleDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = NewRoleDomainEvent.class,
+            domainEvent = newRole.ActionEvent.class,
             semantics = SemanticsOf.IDEMPOTENT
             )
     @ActionLayout(sequence = "100.20.2")
-    public ApplicationRole newRole(
-            @Parameter(maxLength = ApplicationRole.Name.MAX_LENGTH)
-            @ParameterLayout(named="Name", typicalLength= ApplicationRole.Name.TYPICAL_LENGTH)
-            final String name,
-            @Parameter(maxLength = ApplicationRole.Description.MAX_LENGTH, optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named="Description", typicalLength= ApplicationRole.Description.TYPICAL_LENGTH)
-            final String description) {
-        return applicationRoleRepository.newRole(name, description);
+    public class newRole{
+
+        public class ActionEvent extends ActionDomainEvent<newRole> {}
+
+        @MemberSupport public ApplicationRole act (
+                @Parameter(maxLength = ApplicationRole.Name.MAX_LENGTH)
+                @ParameterLayout(named="Name", typicalLength= ApplicationRole.Name.TYPICAL_LENGTH)
+                final String name,
+                @Parameter(maxLength = ApplicationRole.Description.MAX_LENGTH, optionality = Optionality.OPTIONAL)
+                @ParameterLayout(named="Description", typicalLength= ApplicationRole.Description.TYPICAL_LENGTH)
+                final String description) {
+            return applicationRoleRepository.newRole(name, description);
+        }
     }
 
 
-    // -- allRoles
-    public static class AllRolesDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = AllRolesDomainEvent.class,
+            domainEvent = allRoles.ActionEvent.class,
             semantics = SemanticsOf.SAFE
             )
     @ActionLayout(sequence = "100.20.3")
-    public Collection<? extends ApplicationRole> allRoles() {
-        return applicationRoleRepository.allRoles();
+    public class allRoles {
+
+        public class ActionEvent extends ActionDomainEvent<allRoles> {}
+
+        @MemberSupport public Collection<? extends ApplicationRole> act() {
+            return applicationRoleRepository.allRoles();
+        }
+
     }
 
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addChild.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addChild.java
index 24564d9..3aafeb2 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addChild.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addChild.java
@@ -50,8 +50,7 @@ public class ApplicationTenancy_addChild {
 
     private final ApplicationTenancy target;
 
-    @MemberSupport
-    public ApplicationTenancy act(final ApplicationTenancy child) {
+    @MemberSupport public ApplicationTenancy act(final ApplicationTenancy child) {
         applicationTenancyRepository.setParentOnTenancy(child, target);
         return target;
     }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addUser.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addUser.java
index c3c0611..f1211e4 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addUser.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_addUser.java
@@ -57,14 +57,12 @@ public class ApplicationTenancy_addUser {
 
     private final ApplicationTenancy target;
 
-    @MemberSupport
-    public ApplicationTenancy act(final ApplicationUser applicationUser) {
+    @MemberSupport public ApplicationTenancy act(final ApplicationUser applicationUser) {
         applicationTenancyRepository.setTenancyOnUser(target, applicationUser);
         return target;
     }
 
-    @MemberSupport
-    public List<? extends ApplicationUser> autoComplete0Act(final String search) {
+    @MemberSupport public List<? extends ApplicationUser> autoComplete0Act(final String search) {
         final Collection<? extends ApplicationUser> matchingSearch = applicationUserRepository.find(search);
         final List<? extends ApplicationUser> list = _Lists.newArrayList(matchingSearch);
         list.removeAll(applicationUserRepository.findByTenancy(target));
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_delete.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_delete.java
index 7f7f100..ae7284c 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_delete.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_delete.java
@@ -61,8 +61,7 @@ public class ApplicationTenancy_delete {
     private final ApplicationTenancy target;
 
 
-    @MemberSupport
-    public Collection<? extends ApplicationTenancy> act() {
+    @MemberSupport public Collection<? extends ApplicationTenancy> act() {
         for (val user : applicationUserRepository.findByTenancy(target)) {
             val updateAtPathMixin = factoryService.mixin(ApplicationUser_updateAtPath.class, user);
             updateAtPathMixin.act(null);
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeChild.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeChild.java
index 5766eac..6593b9a 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeChild.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeChild.java
@@ -52,20 +52,14 @@ public class ApplicationTenancy_removeChild {
 
     private final ApplicationTenancy target;
 
-    @MemberSupport
-    public ApplicationTenancy act(final ApplicationTenancy child) {
+    @MemberSupport public ApplicationTenancy act(final ApplicationTenancy child) {
         applicationTenancyRepository.clearParentOnTenancy(child);
         return target;
     }
 
-    @MemberSupport
-    public Collection<? extends ApplicationTenancy> choices0Act() {
+    @MemberSupport public Collection<? extends ApplicationTenancy> choices0Act() {
         return applicationTenancyRepository.getChildren(target);
     }
-
-    @MemberSupport
-    public String disableAct() {
-        return choices0Act().isEmpty()? "No children to remove": null;
-    }
+    @MemberSupport public String disableAct() { return choices0Act().isEmpty()? "No children to remove": null; }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeUser.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeUser.java
index 83777c0..9dccc55 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeUser.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_removeUser.java
@@ -55,20 +55,14 @@ public class ApplicationTenancy_removeUser {
 
     private final ApplicationTenancy target;
 
-    @MemberSupport
-    public ApplicationTenancy act(final ApplicationUser applicationUser) {
+    @MemberSupport public ApplicationTenancy act(final ApplicationUser applicationUser) {
         applicationTenancyRepository.clearTenancyOnUser(applicationUser);
         return target;
     }
 
-    @MemberSupport
-    public Collection<? extends ApplicationUser> choices0Act() {
+    @MemberSupport public Collection<? extends ApplicationUser> choices0Act() {
         return applicationUserRepository.findByTenancy(target);
     }
-
-    @MemberSupport
-    public String disableAct() {
-        return choices0Act().isEmpty()? "No users to remove": null;
-    }
+    @MemberSupport public String disableAct() { return choices0Act().isEmpty()? "No users to remove": null; }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_updateName.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_updateName.java
index da19bde..2ff8190 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_updateName.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_updateName.java
@@ -46,17 +46,13 @@ public class ApplicationTenancy_updateName {
 
     private final ApplicationTenancy target;
 
-    @MemberSupport
-    public ApplicationTenancy act(
+    @MemberSupport public ApplicationTenancy act(
             @ApplicationTenancy.Name
             final String name) {
         target.setName(name);
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
-        return target.getName();
-    }
+    @MemberSupport public String default0Act() { return target.getName(); }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_users.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_users.java
index e24dff6..9d0dea6 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_users.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/dom/mixins/ApplicationTenancy_users.java
@@ -22,6 +22,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.extensions.secman.applib.tenancy.dom.ApplicationTenancy;
 import org.apache.isis.extensions.secman.applib.tenancy.dom.ApplicationTenancy.CollectionDomainEvent;
 import org.apache.isis.extensions.secman.applib.user.dom.ApplicationUser;
@@ -45,7 +46,7 @@ public class ApplicationTenancy_users {
     public static class DomainEvent
             extends CollectionDomainEvent<ApplicationUser> {}
 
-    public java.util.Collection<ApplicationUser> coll() {
+    @MemberSupport public java.util.Collection<ApplicationUser> coll() {
         return applicationUserRepository.findByAtPath(target.getPath());
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/menu/ApplicationTenancyMenu.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/menu/ApplicationTenancyMenu.java
index ffb8646..6584e26 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/menu/ApplicationTenancyMenu.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/tenancy/menu/ApplicationTenancyMenu.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.MinLength;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.ObjectSupport;
@@ -52,71 +53,76 @@ public class ApplicationTenancyMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleExtSecmanApplib.NAMESPACE + ".ApplicationTenancyMenu";
 
-    // -- domain event classes
-    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApplib.PropertyDomainEvent<ApplicationTenancyMenu, T> {}
-    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApplib.CollectionDomainEvent<ApplicationTenancyMenu, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApplib.ActionDomainEvent<ApplicationTenancyMenu> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtSecmanApplib.ActionDomainEvent<T> {}
 
     @Inject private ApplicationTenancyRepository applicationTenancyRepository;
 
-    // -- iconName
+
     @ObjectSupport
     public String iconName() {
         return "applicationTenancy";
     }
 
 
-    // -- findTenancies
-    public static class FindTenanciesDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = FindTenanciesDomainEvent.class,
+            domainEvent = findTenancies.ActionEvent.class,
             semantics = SemanticsOf.SAFE
             )
     @ActionLayout(sequence = "100.30.1")
-    public Collection<? extends ApplicationTenancy> findTenancies(
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Partial Name Or Path", describedAs = "String to search for, wildcard (*) can be used")
-            @MinLength(1) // for auto-complete
-            final String partialNameOrPath) {
-        return applicationTenancyRepository.findByNameOrPathMatchingCached(partialNameOrPath);
+    public class findTenancies{
+
+        public class ActionEvent extends ActionDomainEvent<findTenancies> {}
+
+        @MemberSupport public Collection<? extends ApplicationTenancy> act(
+                @Parameter(optionality = Optionality.OPTIONAL)
+                @ParameterLayout(named = "Partial Name Or Path", describedAs = "String to search for, wildcard (*) can be used")
+                @MinLength(1) // for auto-complete
+                final String partialNameOrPath) {
+            return applicationTenancyRepository.findByNameOrPathMatchingCached(partialNameOrPath);
+        }
     }
 
 
-    // -- newTenancy
-    public static class NewTenancyDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = NewTenancyDomainEvent.class,
+            domainEvent = newTenancy.ActionEvent.class,
             semantics = SemanticsOf.IDEMPOTENT
             )
     @ActionLayout(sequence = "100.30.3")
-    public ApplicationTenancy newTenancy(
-            @Parameter(maxLength = ApplicationTenancy.Name.MAX_LENGTH)
-            @ParameterLayout(named = "Name", typicalLength = ApplicationTenancy.Name.TYPICAL_LENGTH)
-            final String name,
-            @Parameter(maxLength = ApplicationTenancy.Path.MAX_LENGTH)
-            @ParameterLayout(named = "Path")
-            final String path,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Parent")
-            final ApplicationTenancy parent) {
-        return applicationTenancyRepository.newTenancy(name, path, parent);
-    }
+    public class newTenancy{
+
+        public class ActionEvent extends ActionDomainEvent<newTenancy> {}
+
+        @MemberSupport public ApplicationTenancy act(
+                @Parameter(maxLength = ApplicationTenancy.Name.MAX_LENGTH)
+                @ParameterLayout(named = "Name", typicalLength = ApplicationTenancy.Name.TYPICAL_LENGTH)
+                final String name,
+                @Parameter(maxLength = ApplicationTenancy.Path.MAX_LENGTH)
+                @ParameterLayout(named = "Path")
+                final String path,
+                @Parameter(optionality = Optionality.OPTIONAL)
+                @ParameterLayout(named = "Parent")
+                final ApplicationTenancy parent) {
+            return applicationTenancyRepository.newTenancy(name, path, parent);
+        }
 
+    }
 
-    // -- allTenancies
-    public static class AllTenanciesDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = AllTenanciesDomainEvent.class,
+            domainEvent = allTenancies.ActionEvent.class,
             semantics = SemanticsOf.SAFE,
             restrictTo = RestrictTo.PROTOTYPING
             )
     @ActionLayout(sequence = "100.30.4")
-    public Collection<? extends ApplicationTenancy> allTenancies() {
-        return applicationTenancyRepository.allTenancies();
-    }
+    public class allTenancies{
 
+        public class ActionEvent extends ActionDomainEvent<allTenancies> {}
+
+        @MemberSupport public Collection<? extends ApplicationTenancy> act() {
+            return applicationTenancyRepository.allTenancies();
+        }
+    }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/ApplicationUserManager.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/ApplicationUserManager.java
index c43c0ac..5b598b5 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/ApplicationUserManager.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/ApplicationUserManager.java
@@ -20,7 +20,7 @@ package org.apache.isis.extensions.secman.applib.user.app;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Nature;
-import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.applib.annotation.ObjectSupport;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
 
 @DomainObject(
@@ -31,8 +31,7 @@ public class ApplicationUserManager {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleExtSecmanApplib.NAMESPACE + ".ApplicationUserManager";
 
-    @Title
-    public String title() {
+    @ObjectSupport public String title() {
         return "Application User Manager";
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_allUsers.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_allUsers.java
index 6d59d29..176dd4c 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_allUsers.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_allUsers.java
@@ -39,8 +39,7 @@ public class ApplicationUserManager_allUsers {
     @Inject
     private ApplicationUserRepository applicationUserRepository;
 
-    @MemberSupport
-    public Collection<ApplicationUser> coll() {
+    @MemberSupport public Collection<ApplicationUser> coll() {
         return applicationUserRepository.allUsers();
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newDelegateUser.java
index 0a53610..f4e6b99 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newDelegateUser.java
@@ -59,8 +59,7 @@ public class ApplicationUserManager_newDelegateUser {
 
     private final ApplicationUserManager target;
 
-    @MemberSupport
-    public ApplicationUserManager act(
+    @MemberSupport public ApplicationUserManager act(
 
           @Parameter(maxLength = ApplicationUser.Username.MAX_LENGTH)
           @ParameterLayout(named = "Name")
@@ -86,8 +85,7 @@ public class ApplicationUserManager_newDelegateUser {
         return target;
     }
 
-    @MemberSupport
-    public ApplicationRole default1Act() {
+    @MemberSupport public ApplicationRole default1Act() {
         return applicationRoleRepository
                 .findByNameCached(configBean.getRegularUserRoleName())
                 .orElse(null);
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newLocalUser.java
index 90d4b14..3936b57 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newLocalUser.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/app/mixins/ApplicationUserManager_newLocalUser.java
@@ -66,8 +66,7 @@ extends ApplicationUserManager_newLocalUserAbstract {
 
     private final ApplicationUserManager target;
 
-    @MemberSupport
-    public ApplicationUserManager act(
+    @MemberSupport public ApplicationUserManager act(
           @Parameter(maxLength = ApplicationUser.Username.MAX_LENGTH)
           @ParameterLayout(named = "Name")
           final String username,
@@ -108,8 +107,7 @@ extends ApplicationUserManager_newLocalUserAbstract {
         return target;
     }
 
-    @MemberSupport
-    public String validateAct(
+    @MemberSupport public String validateAct(
             final String username,
             final Password newPassword,
             final Password newPasswordRepeat,
@@ -124,8 +122,7 @@ extends ApplicationUserManager_newLocalUserAbstract {
         return null;
     }
 
-    @MemberSupport
-    public ApplicationRole default3Act() {
+    @MemberSupport public ApplicationRole default3Act() {
         return applicationRoleRepository
                 .findByNameCached(configBean.getRegularUserRoleName())
                 .orElse(null);
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/contributions/HasUsername_open.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/contributions/HasUsername_open.java
index af9026e..d5879c1 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/contributions/HasUsername_open.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/contributions/HasUsername_open.java
@@ -22,6 +22,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.mixins.security.HasUsername;
 import org.apache.isis.applib.services.i18n.TranslatableString;
@@ -48,22 +49,16 @@ public class HasUsername_open {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApplib.ActionDomainEvent<HasUsername_open> {}
 
-    public ApplicationUser act() {
+    @MemberSupport public ApplicationUser act() {
         if (target == null || target.getUsername() == null) {
             return null;
         }
         return applicationUserRepository.findByUsername(target.getUsername()).orElse(null);
     }
 
-    public boolean hideAct() {
-        return target instanceof ApplicationUser;
-    }
-
-    public TranslatableString disableAct() {
-        if (target == null || target.getUsername() == null) {
-            return TranslatableString.tr("No username");
-        }
-        return null;
+    @MemberSupport public boolean hideAct() { return target instanceof ApplicationUser; }
+    @MemberSupport public TranslatableString disableAct() {
+        return target == null || target.getUsername() == null ? TranslatableString.tr("No username") : null;
     }
 
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/ApplicationUser.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/ApplicationUser.java
index 456cfba..294cc77 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/ApplicationUser.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/ApplicationUser.java
@@ -117,14 +117,12 @@ public abstract class ApplicationUser
     public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApplib.PropertyDomainEvent<ApplicationUser, T> {}
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApplib.CollectionDomainEvent<ApplicationUser, T> {}
 
-    // -- MODEL
 
-    @Title
-    public String title() {
+
+    @ObjectSupport public String title() {
         return getName();
     }
-    @ObjectSupport
-    public String iconName() {
+    @ObjectSupport public String iconName() {
         return getStatus().isUnlocked() ? "unlocked" : "locked";
     }
 
@@ -474,8 +472,7 @@ public abstract class ApplicationUser
     @EncryptedPassword
     public abstract String getEncryptedPassword();
     public abstract void setEncryptedPassword(String encryptedPassword);
-    @MemberSupport
-    public boolean hideEncryptedPassword() {
+    @MemberSupport public boolean hideEncryptedPassword() {
         return !getApplicationUserRepository().isPasswordFeatureEnabled(this);
     }
 
@@ -501,8 +498,7 @@ public abstract class ApplicationUser
     public boolean isHasPassword() {
         return _Strings.isNotEmpty(getEncryptedPassword());
     }
-    @MemberSupport
-    public boolean hideHasPassword() {
+    @MemberSupport public boolean hideHasPassword() {
         return !getApplicationUserRepository().isPasswordFeatureEnabled(this);
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_addRole.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_addRole.java
index 3e3921f..2164b30 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_addRole.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_addRole.java
@@ -24,6 +24,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.extensions.secman.applib.IsisModuleExtSecmanApplib;
@@ -54,20 +55,18 @@ public class ApplicationUser_addRole {
 
     private final ApplicationUser target;
 
-    public ApplicationUser act(final ApplicationRole role) {
+    @MemberSupport public ApplicationUser act(final ApplicationRole role) {
         applicationRoleRepository.addRoleToUser(role, target);
         return target;
     }
 
-    public Collection<? extends ApplicationRole> choices0Act() {
+    @MemberSupport public Collection<? extends ApplicationRole> choices0Act() {
         val allRoles = applicationRoleRepository.allRoles();
         val applicationRoles = _Sets.newTreeSet(allRoles);
         applicationRoles.removeAll(target.getRoles());
         return applicationRoles;
     }
 
-    public String disableAct() {
-        return choices0Act().isEmpty()? "All roles added": null;
-    }
+    @MemberSupport public String disableAct() { return choices0Act().isEmpty()? "All roles added": null; }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_delete.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_delete.java
index 44ba2d0..6d7ae67 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_delete.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_delete.java
@@ -54,14 +54,12 @@ public class ApplicationUser_delete {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public Collection<ApplicationUser> act() {
+    @MemberSupport public Collection<ApplicationUser> act() {
         repository.removeAndFlush(target);
         return applicationUserRepository.allUsers();
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return applicationUserRepository.isAdminUser(target)? "Cannot delete the admin user": null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_duplicate.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_duplicate.java
index f27bda5..0ab7d46 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_duplicate.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_duplicate.java
@@ -18,9 +18,10 @@
  */
 package org.apache.isis.extensions.secman.applib.user.dom.mixins;
 
-import org.springframework.lang.Nullable;
 import javax.inject.Inject;
 
+import org.springframework.lang.Nullable;
+
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
@@ -55,8 +56,7 @@ public class ApplicationUser_duplicate {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             final String username,
             @Nullable
             final String emailAddress) {
@@ -74,5 +74,4 @@ public class ApplicationUser_duplicate {
                 });
 
     }
-
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_lock.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_lock.java
index b779aff..5811802 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_lock.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_lock.java
@@ -53,14 +53,12 @@ public class ApplicationUser_lock {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act() {
+    @MemberSupport public ApplicationUser act() {
         target.setStatus(ApplicationUserStatus.LOCKED);
         return target;
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         if(applicationUserRepository.isAdminUser(target)) {
             return String.format("Cannot lock the '%s' user.", configBean.getAdminUserName());
         }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_removeRoles.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_removeRoles.java
index 7df6bcf..95223b2 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_removeRoles.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_removeRoles.java
@@ -60,8 +60,7 @@ public class ApplicationUser_removeRoles {
     private final ApplicationUser target;
 
 
-    @MemberSupport
-    public ApplicationUser act(Collection<ApplicationRole> roles) {
+    @MemberSupport public ApplicationUser act(Collection<ApplicationRole> roles) {
 
         _NullSafe.stream(roles)
         .filter(this::canRemove)
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_resetPassword.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_resetPassword.java
index 01b56cb..0d1ce30 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_resetPassword.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_resetPassword.java
@@ -52,8 +52,7 @@ public class ApplicationUser_resetPassword {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             final Password newPassword,
             final Password repeatPassword) {
 
@@ -61,13 +60,11 @@ public class ApplicationUser_resetPassword {
         return target;
     }
 
-    @MemberSupport
-    public boolean hideAct() {
+    @MemberSupport public boolean hideAct() {
         return !applicationUserRepository.isPasswordFeatureEnabled(target);
     }
 
-    @MemberSupport
-    public String validateAct(
+    @MemberSupport public String validateAct(
             final Password newPassword,
             final Password repeatPassword) {
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_unlock.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_unlock.java
index 934b2fe..2ef795e 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_unlock.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_unlock.java
@@ -46,14 +46,12 @@ public class ApplicationUser_unlock {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act() {
+    @MemberSupport public ApplicationUser act() {
         target.setStatus(ApplicationUserStatus.UNLOCKED);
         return target;
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return target.getStatus() == ApplicationUserStatus.UNLOCKED ? "Status is already set to UNLOCKED": null;
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAccountType.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAccountType.java
index 2b01f98..32db577 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAccountType.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAccountType.java
@@ -52,21 +52,18 @@ public class ApplicationUser_updateAccountType {
 
     private final ApplicationUser target;
 
-    @MemberSupport
     public ApplicationUser act(final AccountType accountType) {
         target.setAccountType(accountType);
         return target;
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return applicationUserRepository.isAdminUser(target)
                 ? "Cannot change account type for admin user"
                         : null;
     }
 
-    @MemberSupport
-    public AccountType default0Act() {
+    @MemberSupport public AccountType default0Act() {
         return target.getAccountType();
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAtPath.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAtPath.java
index f8947c4..12f7f32 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAtPath.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateAtPath.java
@@ -46,16 +46,14 @@ public class ApplicationUser_updateAtPath {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             @ApplicationUser.AtPath
             final String atPath) {
         target.setAtPath(atPath);
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
+    @MemberSupport public String default0Act() {
         return target.getAtPath();
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateEmailAddress.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateEmailAddress.java
index d988b6b..c859b44 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateEmailAddress.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateEmailAddress.java
@@ -46,21 +46,18 @@ public class ApplicationUser_updateEmailAddress {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             @ApplicationUser.EmailAddress
             final String emailAddress) {
         target.setEmailAddress(emailAddress);
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
+    @MemberSupport public String default0Act() {
         return target.getEmailAddress();
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateFaxNumber.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateFaxNumber.java
index a26c54c..42bff1b 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateFaxNumber.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateFaxNumber.java
@@ -46,21 +46,15 @@ public class ApplicationUser_updateFaxNumber {
 
     private final ApplicationUser holder;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             @ApplicationUser.FaxNumber
             final String fax) {
         holder.setFaxNumber(fax);
         return holder;
     }
 
-    @MemberSupport
-    public String default0Act() {
-        return holder.getFaxNumber();
-    }
-
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String default0Act() { return holder.getFaxNumber(); }
+    @MemberSupport public String disableAct() {
         return holder.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateName.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateName.java
index 8acb8fd..6f7fecb 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateName.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateName.java
@@ -46,8 +46,7 @@ public class ApplicationUser_updateName {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             @ApplicationUser.FamilyName
             final String familyName,
             @ApplicationUser.GivenName
@@ -61,28 +60,14 @@ public class ApplicationUser_updateName {
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
-        return target.getFamilyName();
-    }
-
-    @MemberSupport
-    public String default1Act() {
-        return target.getGivenName();
-    }
-
-    @MemberSupport
-    public String default2Act() {
-        return target.getKnownAs();
-    }
-
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String default0Act() { return target.getFamilyName(); }
+    @MemberSupport public String default1Act() { return target.getGivenName(); }
+    @MemberSupport public String default2Act() { return target.getKnownAs(); }
+    @MemberSupport public String disableAct() {
         return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
 
-    @MemberSupport
-    public String validateAct(final String familyName, final String givenName, final String knownAs) {
+    @MemberSupport public String validateAct(final String familyName, final String givenName, final String knownAs) {
         if(familyName != null && givenName == null) {
             return "Must provide given name if family name has been provided.";
         }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePassword.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePassword.java
index 5e7eb05..24cabdc 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePassword.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePassword.java
@@ -57,8 +57,7 @@ public class ApplicationUser_updatePassword {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             final Password existingPassword,
             final Password newPassword,
             final Password repeatNewPassword) {
@@ -67,13 +66,8 @@ public class ApplicationUser_updatePassword {
         return target;
     }
 
-    @MemberSupport
-    public boolean hideAct() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(target);
-    }
-
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public boolean hideAct() { return !applicationUserRepository.isPasswordFeatureEnabled(target); }
+    @MemberSupport public String disableAct() {
 
         if(!target.isForSelfOrRunAsAdministrator()) {
             return "Can only update password for your own user account.";
@@ -84,8 +78,7 @@ public class ApplicationUser_updatePassword {
         return null;
     }
 
-    @MemberSupport
-    public String validateAct(
+    @MemberSupport public String validateAct(
             final Password existingPassword,
             final Password newPassword,
             final Password repeatNewPassword) {
@@ -111,5 +104,4 @@ public class ApplicationUser_updatePassword {
         return null;
     }
 
-
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePhoneNumber.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePhoneNumber.java
index 6acebd8..77b7a5d 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePhoneNumber.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updatePhoneNumber.java
@@ -46,22 +46,16 @@ public class ApplicationUser_updatePhoneNumber {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             @ApplicationUser.PhoneNumber
             final String phoneNumber) {
         target.setPhoneNumber(phoneNumber);
         return target;
     }
 
-    @MemberSupport
-    public String disableAct() {
+    @MemberSupport public String disableAct() {
         return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
-
-    @MemberSupport
-    public String default0Act() {
-        return target.getPhoneNumber();
-    }
+    @MemberSupport public String default0Act() { return target.getPhoneNumber(); }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateUsername.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateUsername.java
index 6cfb544..9138a93 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateUsername.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/ApplicationUser_updateUsername.java
@@ -46,17 +46,13 @@ public class ApplicationUser_updateUsername {
 
     private final ApplicationUser target;
 
-    @MemberSupport
-    public ApplicationUser act(
+    @MemberSupport public ApplicationUser act(
             @ApplicationUser.Username
             final String username) {
         target.setUsername(username);
         return target;
     }
 
-    @MemberSupport
-    public String default0Act() {
-        return target.getUsername();
-    }
+    @MemberSupport public String default0Act() { return target.getUsername(); }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_effectiveMemberPermissions.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_effectiveMemberPermissions.java
index 727aabb..5a10ea3 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_effectiveMemberPermissions.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_effectiveMemberPermissions.java
@@ -52,8 +52,7 @@ public class ApplicationUser_effectiveMemberPermissions {
 
     private final ApplicationUser user;
 
-    @MemberSupport
-    public List<UserPermissionViewModel> coll() {
+    @MemberSupport public List<UserPermissionViewModel> coll() {
         return applicationFeatureRepository
                 .allMembers()
                 .stream()
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_filterEffectiveMemberPermissions.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_filterEffectiveMemberPermissions.java
index 951ae7c..d5e3086 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_filterEffectiveMemberPermissions.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/ApplicationUser_filterEffectiveMemberPermissions.java
@@ -61,8 +61,7 @@ public class ApplicationUser_filterEffectiveMemberPermissions {
 
     private final ApplicationUser user;
 
-    @MemberSupport
-    public List<UserPermissionViewModel> act(
+    @MemberSupport public List<UserPermissionViewModel> act(
 
             @ParameterLayout(
                     describedAs = ApplicationFeatureChoices.DESCRIBED_AS
@@ -78,8 +77,7 @@ public class ApplicationUser_filterEffectiveMemberPermissions {
             .collect(Collectors.toList());
     }
 
-    @MemberSupport
-    public java.util.Collection<ApplicationFeatureChoices.AppFeat> autoComplete0Act(
+    @MemberSupport public java.util.Collection<ApplicationFeatureChoices.AppFeat> autoComplete0Act(
             final @MinLength(3) String search) {
         return applicationFeatureChoices.autoCompleteFeature(search);
     }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/UserPermissionViewModel.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/UserPermissionViewModel.java
index 7bb82d4..166289b 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/UserPermissionViewModel.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/dom/mixins/perms/UserPermissionViewModel.java
@@ -40,7 +40,6 @@ import org.apache.isis.applib.annotation.ObjectSupport;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
-import org.apache.isis.applib.annotation.Title;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.appfeat.ApplicationFeature;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
@@ -111,13 +110,11 @@ public class UserPermissionViewModel implements ViewModel {
 
     // -- identification
 
-    @Title
-    public String title() {
+    @ObjectSupport public String title() {
         return getVerb() + " " + getFeatureId().getFullyQualifiedName();
     }
 
-    @ObjectSupport
-    public String iconName() {
+    @ObjectSupport public String iconName() {
         return "userPermission";
     }
 
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/ApplicationUserMenu.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/ApplicationUserMenu.java
index 41b4285..8f45f82 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/ApplicationUserMenu.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/ApplicationUserMenu.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.ObjectSupport;
 import org.apache.isis.applib.annotation.ParameterLayout;
@@ -53,47 +54,54 @@ public class ApplicationUserMenu {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleExtSecmanApplib.NAMESPACE + ".ApplicationUserMenu";
 
-    public static abstract class ActionDomainEvent
-        extends IsisModuleExtSecmanApplib.ActionDomainEvent<ApplicationUserMenu> { }
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtSecmanApplib.ActionDomainEvent<T> { }
 
     private final ApplicationUserRepository applicationUserRepository;
     private final FactoryService factory;
 
 
-    @ObjectSupport
-    public String iconName() {
+    @ObjectSupport public String iconName() {
         return "applicationUser";
     }
 
 
 
-    public static class FindUsersByNameDomainEvent
-        extends ActionDomainEvent { }
-
     @Action(
-            domainEvent = FindUsersByNameDomainEvent.class,
+            domainEvent = findUsers.ActionEvent.class,
             semantics = SemanticsOf.SAFE
     )
     @ActionLayout(sequence = "100.10.2")
-    public Collection<? extends ApplicationUser> findUsers(
-            final @ParameterLayout(named = "Search") String search) {
-        return applicationUserRepository.find(search);
+    public class findUsers{
+
+        public class ActionEvent
+                extends ActionDomainEvent<findUsers> { }
+
+        @MemberSupport public Collection<? extends ApplicationUser> act(
+                final @ParameterLayout(named = "Search") String search) {
+            return applicationUserRepository.find(search);
+        }
+
     }
 
 
 
-    public static class UserManagerDomainEvent extends ActionDomainEvent { }
 
     @Action(
-            domainEvent = UserManagerDomainEvent.class,
+            domainEvent = userManager.ActionEvent.class,
             semantics = SemanticsOf.IDEMPOTENT
     )
     @ActionLayout(
             sequence = "100.10.3",
             cssClassFa = "user-plus"
     )
-    public ApplicationUserManager userManager() {
-        return factory.viewModel(new ApplicationUserManager());
+    public class userManager{
+
+        public class ActionEvent extends ActionDomainEvent<userManager> { }
+
+        @MemberSupport public ApplicationUserManager act(){
+            return factory.viewModel(new ApplicationUserManager());
+        }
+
     }
 
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/MeService.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/MeService.java
index d847e85..9dafa4c 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/MeService.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/user/menu/MeService.java
@@ -27,8 +27,10 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.Domain;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.ObjectSupport;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
@@ -61,23 +63,20 @@ public class MeService {
 
     public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApplib.PropertyDomainEvent<MeService, T> {}
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApplib.CollectionDomainEvent<MeService, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApplib.ActionDomainEvent<MeService> {}
+    public static abstract class ActionDomainEvent<T> extends IsisModuleExtSecmanApplib.ActionDomainEvent<T> {}
 
     final ApplicationUserRepository applicationUserRepository;
     final UserService userService;
     final javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
-    // -- iconName
-    @ObjectSupport
-    public String iconName() {
+
+    @ObjectSupport public String iconName() {
         return "applicationUser";
     }
 
-    // -- me (action)
-    public static class MeDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = MeDomainEvent.class,
+            domainEvent = me.ActionEvent.class,
             semantics = SemanticsOf.SAFE
             )
     @ActionLayout(
@@ -87,33 +86,35 @@ public class MeService {
             sequence = "100"
             )
 
-    public ApplicationUser me() {
-        return queryResultsCacheProvider.get().execute(new Callable<ApplicationUser>() {
-            @Override
-            public ApplicationUser call() throws Exception {
-                return doMe();
-            }
-        }, MeService.class, "me");
-    }
+    public class me{
 
-    protected ApplicationUser doMe() {
-        final String myName = userService.currentUserNameElseNobody();
-        return applicationUserRepository.findOrCreateUserByUsername(myName);
-    }
+        public class ActionEvent extends ActionDomainEvent<me> {}
+
+        @MemberSupport public ApplicationUser act() {
+            return queryResultsCacheProvider.get().execute(
+                    (Callable<ApplicationUser>) this::doMe, MeService.class, "me");
+        }
+
+        @Domain.Exclude protected ApplicationUser doMe() {
+            final String myName = userService.currentUserNameElseNobody();
+            return applicationUserRepository.findOrCreateUserByUsername(myName);
+        }
+
+        @Domain.Exclude protected ApplicationUser doMe(final String myName) {
+            return applicationUserRepository.findOrCreateUserByUsername(myName);
+        }
 
-    protected ApplicationUser doMe(final String myName) {
-        return applicationUserRepository.findOrCreateUserByUsername(myName);
     }
 
 
     @Component
-    @RequiredArgsConstructor(onConstructor_ = {@Inject})
+    @RequiredArgsConstructor
     public static class UserMenuMeActionAdvisor {
 
         final IsisConfiguration isisConfiguration;
 
-        @EventListener(UserMenu.MeDomainEvent.class)
-        public void on(final UserMenu.MeDomainEvent event) {
+        @EventListener(UserMenu.me.ActionEvent.class)
+        public void on(final UserMenu.me.ActionEvent event) {
             switch (isisConfiguration.getExtensions().getSecman().getUserMenuMeActionPolicy()) {
                 case HIDE:
                     event.hide();
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java
index c7f1657..61ec1b9 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java
@@ -28,6 +28,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
@@ -58,13 +59,12 @@ public class JdoMetamodelMenu {
     final JdoSupportService jdoSupport;
     final JdoFacetContext jdoFacetContext;
 
-    public static abstract class ActionDomainEvent
-    extends IsisModuleApplib.ActionDomainEvent<JdoMetamodelMenu> {}
+    public static abstract class ActionDomainEvent<T>
+    extends IsisModuleApplib.ActionDomainEvent<T> {}
 
-    public static class DownloadJdoMetamodelDomainEvent extends ActionDomainEvent {}
 
     @Action(
-            domainEvent = DownloadJdoMetamodelDomainEvent.class,
+            domainEvent = downloadMetamodels.ActionEvent.class,
             semantics = SemanticsOf.NON_IDEMPOTENT, //disable client-side caching
             restrictTo = RestrictTo.PROTOTYPING
             )
@@ -72,12 +72,17 @@ public class JdoMetamodelMenu {
             cssClassFa = "fa-download",
             named = "Download JDO Metamodels (ZIP)",
             sequence="500.670.1")
-    public Blob downloadMetamodels() {
+    public class downloadMetamodels{
 
-        final byte[] zipBytes = zip();
-        return Blob.of("jdo-metamodels", CommonMimeType.ZIP, zipBytes);
+        public class ActionEvent extends ActionDomainEvent<downloadMetamodels> {}
+
+        @MemberSupport public Blob act() {
+            final byte[] zipBytes = zip();
+            return Blob.of("jdo-metamodels", CommonMimeType.ZIP, zipBytes);
+        }
     }
 
+
     // -- HELPER
 
     private byte[] zip() {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/SwaggerServiceMenu.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/SwaggerServiceMenu.java
index 2f64170..5e45398 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/SwaggerServiceMenu.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/SwaggerServiceMenu.java
@@ -31,6 +31,7 @@ import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
@@ -75,77 +76,89 @@ public class SwaggerServiceMenu {
     }
 
     public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<SwaggerServiceMenu> { }
-    public static class OpenSwaggerUiDomainEvent extends ActionDomainEvent { }
 
     @Action(
             semantics = SemanticsOf.SAFE,
-            domainEvent = OpenSwaggerUiDomainEvent.class,
+            domainEvent = openSwaggerUi.ActionEvent.class,
             restrictTo = RestrictTo.PROTOTYPING
             )
     @ActionLayout(
             cssClassFa = "fa-external-link-alt",
             sequence="500.600.1")
-    public LocalResourcePath openSwaggerUi() {
+    public class openSwaggerUi {
+        public class ActionEvent extends ActionDomainEvent { }
+
+        public LocalResourcePath act() {
         return new LocalResourcePath("/swagger-ui/index.thtml");
     }
     @MemberSupport
-    public String disableOpenSwaggerUi() {
-        return disableReasonWhenRequiresROViewer();
+        public String disableAct() {
+            return disableReasonWhenRequiresROViewer();
+        }
     }
 
-    public static class OpenRestApiDomainEvent extends ActionDomainEvent { }
+
+
 
     @Action(
             semantics = SemanticsOf.SAFE,
-            domainEvent = OpenSwaggerUiDomainEvent.class,
+            domainEvent = openRestApi.ActionEvent.class,
             restrictTo = RestrictTo.PROTOTYPING
             )
     @ActionLayout(
             cssClassFa = "fa-external-link-alt",
             sequence="500.600.2")
-    public LocalResourcePath openRestApi() {
-        return new LocalResourcePath(basePath);
-    }
+    public class openRestApi {
+
+        public class ActionEvent extends ActionDomainEvent { }
+
+        LocalResourcePath act() {
+            return new LocalResourcePath(basePath);
+        }
     @MemberSupport
-    public String disableOpenRestApi() {
-        return disableReasonWhenRequiresROViewer();
+        @MemberSupport String disableAct() {
+            return disableReasonWhenRequiresROViewer();
+        }
     }
 
-    public static class DownloadSwaggerSpecDomainEvent extends ActionDomainEvent { }
+
 
     @Action(
             semantics = SemanticsOf.SAFE,
-            domainEvent = DownloadSwaggerSpecDomainEvent.class,
+            domainEvent = downloadSwaggerSchemaDefinition.ActionEvent.class,
             restrictTo = RestrictTo.PROTOTYPING
             )
     @ActionLayout(
             cssClassFa = "fa-download",
             sequence="500.600.3")
-    public Clob downloadSwaggerSchemaDefinition(
-            @ParameterLayout(named = "Filename")
-            final String fileNamePrefix,
-            final Visibility visibility,
-            final Format format) {
 
-        final String fileName = buildFileName(fileNamePrefix, visibility, format);
-        final String spec = swaggerService.generateSwaggerSpec(visibility, format);
-        return new Clob(fileName, format.mediaType(), spec);
-    }
-    @MemberSupport
-    public String default0DownloadSwaggerSchemaDefinition() {
-        return "swagger";
-    }
-    @MemberSupport
-    public Visibility default1DownloadSwaggerSchemaDefinition() {
-        return Visibility.PRIVATE;
-    }
-    @MemberSupport
-    public Format default2DownloadSwaggerSchemaDefinition() {
-        return Format.YAML;
+    public class downloadSwaggerSchemaDefinition {
+
+        public class ActionEvent extends ActionDomainEvent { }
+
+        public Clob act(
+                @ParameterLayout(named = "Filename")
+                final String fileNamePrefix,
+                final Visibility visibility,
+                final Format format) {
+
+            val fileName = buildFileName(fileNamePrefix, visibility, format);
+            val spec = swaggerService.generateSwaggerSpec(visibility, format);
+            return new Clob(fileName, format.mediaType(), spec);
+        }
+
+        @MemberSupport public String default0Act() { return "swagger"; }
+        @MemberSupport public Visibility default1Act() {
+            return Visibility.PRIVATE;
+        }
+        @MemberSupport public Format default2Act() {
+            return Format.YAML;
+        }
     }
 
-    // -- HELPER
 
+    // -- HELPER
+    @Programmatic
     private String disableReasonWhenRequiresROViewer() {
         final Optional<?> moduleIfAny = serviceRegistry
                 .lookupBeanById("isis.viewer.ro.WebModuleJaxrsRestEasy4");