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/05/05 04:57:03 UTC

[isis] branch ISIS-2619 updated (fb301fb -> 6764fae)

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

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


 discard fb301fb  ISIS-2614 and ISIS-2609: removes Application.getName ; moves mixin domain events down from API to model
     add 6f20d66  Merge pull request #512 from apache/ISIS-2619
     add 5a9e5b5  ISIS-2619: minor housekeeping
     add c8420fb  ISIS-2619: minor code de-duplication
     add 56274bf  ISIS-2297: batch organize imports on meta-model module
     add 9f4dba5  ISIS-2620: Demo Wicket: split into JDO/JPA
     add 4b90e76  ISIS-2620: update demo-wicket docker adoc
     add 0422daf  ISIS-2620: supposed fix for docker image build
     add 4a15720  ISIS-2620: add JPA converters for asciidoc/markdown
     add 9297c36  ISIS-2620: fix demo docker jib conf: use jdo/jpa suffixed image names
     add df277e4  ISIS-2620: split demo configuration classes into JDO/JPA
     add af5eee2  ISIS-2620: Demo: start adding profile annotations
     add 9f25f84  ISIS-2640: add new BeanSort: VETOED
     add 25338ff  ISIS-2641: introduce a new BeanSort: ABSTRACT
     add a8221bc  API (minor): add new method to TreeNode to simplify expand
     add e6b062f  ISIS-2641: let IsisBeanTypeClassififer also handle non-concrete types
     add 3f9baa3  ISIS-2641: a bit of SpecLoader housekeeping
     add fc37740  ISIS-2641: more MM housekeeping
     add bd22f8b  ISIS-2641: MM: support return types with generic wildcard type args
     add e42c54c  ISIS-2641: remove debug lines
     add a5c3884  ISIS-2642: introduce _Generics utility to consolidate type argument logic
     add da959b2  ISIS-2642: fixes copy paste error from prev. commit
     add fcad93b  ISIS-2642: disable reg.test thats not yet working
     add 4659472  ISIS-2642: _Generics: use Stream- instead of Visitor-pattern
     add 2bba910  ISIS-2642: _Generics: consolidate TypeOfFacet
     add 50010e7  ISIS-2642: simplify TypeOfFacet utilities
     add eaa0944  ISIS-2642: _Generics: consolidate _Collections
     add ac9fada  ISIS-2642: active MM tests; also add some java-doc
     add ed0416b  ISIS-2641: SecMan: housekeeping ApplicationFeatureViewModel helpers
     add 35298a3  ISIS-2641: MM: fix abstract type detection
     add 5e78314  ISIS-2641: just some notes
     new 6764fae  ISIS-2614 and ISIS-2609: removes Application.getName ; moves mixin domain events down from API to model

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (fb301fb)
            \
             N -- N -- N   refs/heads/ISIS-2619 (6764fae)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

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


Summary of changes:
 .../apache/isis/applib/graph/tree/TreeNode.java    |   11 +
 .../isis/applib/services/metamodel/BeanSort.java   |   25 +-
 .../org/apache/isis/commons/collections/Can.java   |   13 +
 .../apache/isis/commons/collections/Can_Empty.java |    5 +
 .../isis/commons/internal/collections/_Arrays.java |    8 +-
 .../commons/internal/collections/_Collections.java |  123 +-
 .../commons/internal/reflection/_Annotations.java  |   16 +-
 .../commons/internal/reflection/_Generics.java     |  140 ++
 .../commons/internal/collections/_ArraysTest.java  |    6 +-
 .../IsisBeanFactoryPostProcessorForSpring.java     |   30 +-
 .../core/config/beans/IsisBeanTypeClassifier.java  |   20 +-
 .../config/beans/IsisBeanTypeClassifierImpl.java   |   65 +-
 .../config/beans/IsisBeanTypeRegistryDefault.java  |    2 +
 .../beans/IsisComponentScanInterceptorImpl.java    |    1 -
 .../_testing/MetaModelContext_forTesting.java      |    4 +-
 .../_testing/ServiceInjector_forTesting.java       |    4 +-
 .../metamodel/_testing/_ServiceInjectorLegacy.java |    3 +-
 .../metamodel/commons/CanonicalParameterUtil.java  |    6 +-
 .../isis/core/metamodel/facets/FacetedMethod.java  |   44 +-
 .../facets/actcoll/typeof/TypeOfFacet.java         |  151 +-
 .../action/ActionAnnotationFacetFactory.java       |   13 +-
 .../CollectionAnnotationFacetFactory.java          |   32 +-
 .../DeriveMixinMembersPostProcessor.java           |    3 +-
 .../ObjectSpecificationPostProcessorAbstract.java  |   17 +
 .../DeriveDescribedAsFromTypePostProcessor.java    |   17 -
 .../all/i18n/TranslationPostProcessor.java         |    4 -
 ...ectionParamDefaultsAndChoicesPostProcessor.java |    2 -
 .../TweakDomainEventsForMixinPostProcessor.java    |    6 -
 .../DeriveDisabledFromImmutablePostProcessor.java  |   10 +-
 .../DeriveDisabledFromViewModelPostProcessor.java  |   10 -
 ...iveChoicesFromExistingChoicesPostProcessor.java |   18 -
 .../DeriveDefaultFromTypePostProcessor.java        |   18 -
 .../DeriveTypicalLengthFromTypePostProcessor.java  |   17 -
 .../dflt/ProgrammingModelFacetsJava8.java          |   16 +-
 .../core/metamodel/services/CollectionHelper.java  |   14 +-
 .../ApplicationFeatureRepositoryDefault.java       |   13 +-
 .../services/metamodel/DomainMemberDefault.java    |   19 +-
 .../metamodel/MetaModelServiceDefault.java         |   37 +-
 .../isis/core/metamodel/spec/Hierarchical.java     |    6 +-
 .../core/metamodel/spec/feature/ObjectAction.java  |    2 -
 .../spec/feature/ObjectAssociationContainer.java   |   14 +
 .../specloader/SpecificationLoaderDefault.java     |    2 +-
 .../specimpl/ObjectSpecificationAbstract.java      |   86 +-
 .../specimpl/dflt/ObjectSpecificationDefault.java  |    4 +-
 .../specloader/typeextract/TypeExtractor.java      |   30 +-
 .../specloader/validator/ValidationFailure.java    |    6 +-
 .../metamodel/MetaModelContext_configTest.java     |    4 +-
 .../metamodel/commons/ListUtilsTest_insert.java    |    4 +-
 .../metamodel/consent/InteractionResultTest.java   |    4 +-
 .../facetapi/FeatureTypeTest_identifierFor.java    |    6 +-
 .../Annotations_getAnnotations_on_Class_Test.java  |    6 +-
 .../Annotations_getAnnotations_on_Field_Test.java  |    6 +-
 .../Annotations_getAnnotations_on_Method_Test.java |    4 +-
 ...notations_getAnnotations_on_Parameter_Test.java |    4 +-
 .../metamodel/facets/CollectionFacetUtilsTest.java |    6 +-
 ...nEventHelperTest_newActionInteractionEvent.java |   11 +-
 ...HelperTest_newCollectionDomainEvent_forAdd.java |    8 +-
 ...perTest_newCollectionDomainEvent_forRemove.java |    8 +-
 ...HelperTest_newPropertyDomainEvent_forClear.java |    9 +-
 ...elperTest_newPropertyDomainEvent_forModify.java |    6 +-
 .../metamodel/facets/MethodFinderUtilsTest.java    |    6 +-
 .../metamodel/facets/ObjectAdapterUtilsTest.java   |    6 +-
 .../ActionAnnotationFacetFactoryTest_Hidden.java   |    6 +-
 ...ctionAnnotationFacetFactoryTest_Invocation.java |    3 +-
 ...ctionAnnotationFacetFactoryTest_RestrictTo.java |    4 +-
 ...ActionAnnotationFacetFactoryTest_Semantics.java |    6 +-
 .../ActionAnnotationFacetFactoryTest_TypeOf.java   |    5 +-
 ...notationFacetFactoryTest_commandPublishing.java |    8 +-
 ...tationFacetFactoryTest_executionPublishing.java |    8 +-
 ...nLayoutXmlLayoutAnnotationFacetFactoryTest.java |   12 +-
 ...etDerivedFromDomainServiceFacetFactoryTest.java |    8 +-
 .../prototype/PrototypeFacetAbstractTest.java      |    4 +-
 .../collections/JavaCollectionFacetTest.java       |    6 +-
 .../CollectionAnnotationFacetFactoryTest.java      |   15 +-
 ...etForCollectionLayoutAnnotationFactoryTest.java |   12 +-
 .../ViewModelSemanticCheckingFacetFactoryTest.java |    8 +-
 ...okmarkableAnnotationFacetFactoryTest_class.java |    6 +-
 .../DomainObjectAnnotationFacetFactoryTest.java    |   10 +-
 .../ObjectTypeAnnotationFacetFactoryTest.java      |   10 +-
 .../DomainObjectLayoutFactoryTest.java             |   14 +-
 .../DomainServiceLayoutFacetFactoryTest.java       |    4 +-
 .../cssclass/CssClassFacetMethodFactoryTest.java   |   10 +-
 .../ident/cssclass/CssClassFacetMethodTest.java    |    8 +-
 .../CssClassFacetMethodWithProblemTest.java        |    8 +-
 .../ident/icon/IconFacetMethodFactoryTest.java     |   10 +-
 .../object/ident/icon/IconFacetMethodTest.java     |    8 +-
 .../ident/layout/LayoutFacetFactoryTest.java       |   10 +-
 .../object/ident/layout/LayoutFacetMethodTest.java |    8 +-
 .../ident/title/TitleFacetViaMethodTest.java       |    6 +-
 .../TitleAnnotationFacetFactoryTest.java           |    6 +-
 .../TitleFacetViaTitleAnnotationTest.java          |    6 +-
 .../object/layoutxml/GridFacetDefaultTest.java     |    4 +-
 .../facets/object/mixin/MixinIntendedAs.java       |    4 +-
 .../object/mixin/MixinIntendedAsActionTest.java    |   10 +-
 .../navparent/NavigableParentFacetMethodTest.java  |    8 +-
 ...SpecIdFacetDerivedFromClassNameFactoryTest.java |   10 +-
 ...cetForParameterLayoutAnnotationFactoryTest.java |   10 +-
 ...cetForParameterLayoutAnnotationFactoryTest.java |   12 +-
 .../facets/param/name/ParameterNameFacetTest.java  |    6 +-
 .../ParameterAnnotationFacetFactoryTest.java       |    8 +-
 ...romptStyleFacetFromPropertyAnnotation_Test.java |    6 +-
 ...sabledAnnotationOnPropertyFacetFactoryTest.java |    6 +-
 ...sistedAnnotationOnPropertyFacetFactoryTest.java |    2 +-
 .../PropertyAnnotationFacetFactoryTest.java        |   10 +-
 ...acetForPropertyLayoutAnnotationFactoryTest.java |   12 +-
 ...acetForPropertyLayoutAnnotationFactoryTest.java |   12 +-
 .../specification/SpecificationAndTests.java       |    6 +-
 .../specification/SpecificationNotTests.java       |    6 +-
 .../specification/SpecificationOrTests.java        |    6 +-
 .../BigDecimalValueSemanticsProviderTest.java      |    6 +-
 .../value/BigIntValueSemanticsProviderTest.java    |    6 +-
 .../value/BlobValueSemanticsProviderTest.java      |    8 +-
 .../value/BooleanValueSemanticsProviderTest.java   |    6 +-
 .../value/ByteValueSemanticsProviderTest.java      |    6 +-
 .../value/CharacterValueSemanticsProviderTest.java |    6 +-
 .../value/ClobValueSemanticsProviderTest.java      |    8 +-
 .../value/DoubleValueSemanticsProviderTest.java    |    6 +-
 .../value/FloatValueSemanticsProviderTest.java     |    6 +-
 .../value/IntValueSemanticsProviderTest.java       |    6 +-
 .../JavaSqlDateValueSemanticsProviderTest.java     |    6 +-
 .../JavaSqlTimeValueSemanticsProviderTest.java     |    4 +-
 .../JavaUtilDateValueSemanticsProviderTest.java    |    6 +-
 .../value/LongValueSemanticsProviderTest.java      |    6 +-
 .../value/PasswordValueSemanticsProviderTest.java  |    4 +-
 .../value/ShortValueSemanticsProviderTest.java     |    6 +-
 .../value/StringValueSemanticsProviderTest.java    |    4 +-
 .../ValueSemanticsProviderAbstractTestCase.java    |   14 +-
 ...odaLocalDateTimeValueSemanticsProviderTest.java |    8 +-
 ...jectAssociationPredicatesTest_visibleWhere.java |    6 +-
 .../interactions/InteractionUtils_isA_Test.java    |    3 +-
 .../objects/ObjectActionLayoutXmlDefaultTest.java  |   10 +-
 .../objects/OneToManyAssociationDefaultTest.java   |   10 +-
 .../objects/TypeExtractorMethodReturnTest.java     |   42 +-
 .../TypeExtractorMethodsParametersTest.java        |    4 +-
 .../ServiceInjectorDefaultTest_usingFields.java    |    6 +-
 ...erviceInjectorDefaultTest_validateServices.java |    6 +-
 ...InjectorDefaultTest_validateServices_happy.java |    4 +-
 .../services/appfeat/ApplicationFeatureIdTest.java |   10 +-
 .../ApplicationFeatureRepositoryDefaultTest.java   |   14 +-
 .../services/appfeat/ApplicationFeatureTest.java   |    6 +-
 .../appfeat/ApplicationFeatureTypeTest.java        |    6 +-
 ...zerForRecoverableException_recognizes_Test.java |    6 +-
 .../core/metamodel/services/grid/BS3GridTest.java  |    9 +-
 .../metamodel/MetaModelServiceDefaultTest.java     |    3 +-
 .../services/title/TitleServiceDefaultTest.java    |    6 +-
 .../specloader/SpecificationCacheDefaultTest.java  |   10 +-
 .../SpecificationLoaderTestAbstract.java           |   10 +-
 .../specloader/SpecificationLoaderTest_array.java  |    8 +-
 .../SpecificationLoaderTest_collection.java        |    8 +-
 .../specloader/SpecificationLoaderTest_value.java  |    4 +-
 .../ClassSubstitutorTest_getClass.java             |    4 +-
 .../specimpl/ObjectActionMixedInTest.java          |    4 +-
 ...ionParameterAbstractTest_getId_and_getName.java |    6 +-
 .../specimpl/ObjectAssociationAbstractTest.java    |    6 +-
 ...ObjectAssociationAbstractTest_alwaysHidden.java |   10 +-
 .../specimpl/OneToOneAssociationAbstractTest.java  |    6 +-
 .../testspec/ObjectSpecificationStub.java          |   12 +-
 examples/demo/docker-compose.yml                   |    4 +-
 examples/demo/domain/pom.xml                       |    8 +
 .../src/main/adoc/modules/demo/pages/about.adoc    |   12 +-
 .../dom/{DemoModule.java => DemoModuleCommon.java} |   13 +-
 .../dom/{DemoModule.java => DemoModuleJdo.java}    |   38 +-
 .../src/main/java/demoapp/dom/DemoModuleJpa.java}  |   28 +-
 .../nature/viewmodels/jaxbrefentity/ChildJdo.java  |    3 +
 .../objects/other/embedded/NumberConstantJdo.java  |    3 +
 .../embedded/NumberConstantJdoRepository.java      |    2 +
 .../core/eventbusservice/EventLogEntryJdo.java     |    3 +
 .../EventLogEntryJdoRepository.java                |    2 +
 .../extensions/secman/apptenancy/AppTenancyVm.java |    3 +
 .../ApplicationTenancyEvaluatorForDemo.java        |    2 +
 .../secman/apptenancy/entities/TenantedJdo.java    |    3 +
 .../apptenancy/entities/TenantedJdoEntities.java   |    2 +
 .../entities/seed/TenantedJdoSeedService.java      |    2 +
 .../main/java/demoapp/javafx/DemoAppJavaFx.java    |    4 +-
 .../javafx/integtest/DemoFxTestAbstract.java       |    4 +-
 examples/demo/pom.xml                              |   25 +-
 .../java/demoapp/webapp/vaadin/DemoAppVaadin.java  |    4 +-
 ...AppManifest.java => DemoAppManifestCommon.java} |   11 +-
 .../main/java/demoapp/web/DemoAppManifestJdo.java} |   30 +-
 .../main/java/demoapp/web/DemoAppManifestJpa.java} |   30 +-
 examples/demo/wicket/{ => common}/pom.xml          |  101 +-
 .../common}/ui/custom/WhereInTheWorldPanel.html    |    0
 .../common}/ui/custom/WhereInTheWorldPanel.java    |    2 +-
 .../ui/custom/WhereInTheWorldPanelFactory.java     |    4 +-
 examples/demo/wicket/{ => jdo}/pom.xml             |   73 +-
 .../webapp/wicket/jdo/DemoAppWicketJdo.java}       |   15 +-
 .../{ => jdo}/src/main/resources/log4j2-spring.xml |    0
 .../e2e/cypress-scaffolding/fixtures/example.json  |    0
 .../integration/examples/actions.spec.js           |    0
 .../integration/examples/aliasing.spec.js          |    0
 .../integration/examples/assertions.spec.js        |    0
 .../integration/examples/connectors.spec.js        |    0
 .../integration/examples/cookies.spec.js           |    0
 .../integration/examples/cypress_api.spec.js       |    0
 .../integration/examples/files.spec.js             |    0
 .../integration/examples/local_storage.spec.js     |    0
 .../integration/examples/location.spec.js          |    0
 .../integration/examples/misc.spec.js              |    0
 .../integration/examples/navigation.spec.js        |    0
 .../integration/examples/network_requests.spec.js  |    0
 .../integration/examples/querying.spec.js          |    0
 .../examples/spies_stubs_clocks.spec.js            |    0
 .../integration/examples/traversal.spec.js         |    0
 .../integration/examples/utilities.spec.js         |    0
 .../integration/examples/viewport.spec.js          |    0
 .../integration/examples/waiting.spec.js           |    0
 .../integration/examples/window.spec.js            |    0
 .../integration/typescript/basic.ts                |    0
 .../wicket/{ => jdo}/src/test/e2e/cypress.json     |    0
 .../src/test/e2e/cypress/integration/login.ts      |    0
 .../src/test/e2e/cypress/plugins/index.js          |    0
 .../src/test/e2e/cypress/support/commands.js       |    0
 .../src/test/e2e/cypress/support/index.js          |    0
 examples/demo/wicket/{ => jpa}/pom.xml             |   55 +-
 .../webapp/wicket/jpa/DemoAppWicketJpa.java}       |   27 +-
 .../main => jpa/src}/resources/log4j2-spring.xml   |    0
 .../demo/wicket/src/test/e2e/package-lock.json     | 1527 --------------------
 examples/demo/wicket/src/test/e2e/package.json     |   21 -
 examples/demo/wicket/src/test/e2e/tsconfig.json    |   69 -
 .../commandlog/model/command/CommandModel.java     |   31 +-
 .../commandlog/jdo/entities/CommandJdo.java        |   20 +-
 extensions/core/command-log/jpa/pom.xml            |   25 +-
 .../commandlog/jpa/IsisModuleExtCommandLogJpa.java |   41 +-
 .../commandlog/jpa/entities/CommandJpa.java}       |  126 +-
 .../jpa/entities/CommandJpaRepository.java         |  325 +++++
 .../dom/feature/ApplicationFeatureViewModel.java   |   57 +-
 .../dom/feature/ApplicationFeatureViewModels.java  |   13 +-
 .../model/dom/feature/ApplicationNamespace.java    |    2 +-
 .../secman/model/dom/feature/ApplicationType.java  |    6 +-
 .../facets/TenantedAuthorizationPostProcessor.java |   35 +-
 .../DomainModelTest_usingGoodDomain.java           |   86 ++
 .../testdomain/model/good/ElementTypeAbstract.java |   33 +-
 .../testdomain/model/good/ElementTypeConcrete.java |   20 +-
 .../model/good/ElementTypeInterface.java           |   39 +-
 .../testdomain/model/good/ProperElementTypeVm.java |   50 +-
 scripts/ci/build-artifacts.sh                      |    3 +-
 valuetypes/asciidoc/persistence/jdo-dn5/pom.xml    |    1 -
 .../jdo/dn5/converters/IsisAsciiDocConverter.java  |    4 +-
 .../asciidoc/persistence/{jdo-dn5 => jpa}/pom.xml  |   14 +-
 .../jpa/IsisModuleValAsciidocPersistenceJpa.java   |   25 +-
 .../jpa}/converters/IsisAsciiDocConverter.java     |   18 +-
 valuetypes/asciidoc/persistence/pom.xml            |    1 +
 valuetypes/markdown/persistence/jdo-dn5/pom.xml    |    1 -
 .../jdo/dn5/converters/IsisMarkdownConverter.java  |    7 +-
 .../markdown/persistence/{jdo-dn5 => jpa}/pom.xml  |   14 +-
 .../jpa/IsisModuleValMarkdownPersistenceJpa.java   |   25 +-
 .../jpa}/converters/IsisMarkdownConverter.java     |   16 +-
 valuetypes/markdown/persistence/pom.xml            |    1 +
 valuetypes/pom.xml                                 |   10 +
 249 files changed, 1847 insertions(+), 3251 deletions(-)
 create mode 100644 commons/src/main/java/org/apache/isis/commons/internal/reflection/_Generics.java
 copy examples/demo/domain/src/main/java/demoapp/dom/{DemoModule.java => DemoModuleCommon.java} (87%)
 rename examples/demo/domain/src/main/java/demoapp/dom/{DemoModule.java => DemoModuleJdo.java} (53%)
 copy examples/demo/{wicket/src/test/e2e/cypress/integration/login.ts => domain/src/main/java/demoapp/dom/DemoModuleJpa.java} (61%)
 rename examples/demo/web/src/main/java/demoapp/web/{DemoAppManifest.java => DemoAppManifestCommon.java} (94%)
 copy examples/demo/{wicket/src/test/e2e/cypress/integration/login.ts => web/src/main/java/demoapp/web/DemoAppManifestJdo.java} (61%)
 copy examples/demo/{wicket/src/test/e2e/cypress/integration/login.ts => web/src/main/java/demoapp/web/DemoAppManifestJpa.java} (61%)
 copy examples/demo/wicket/{ => common}/pom.xml (56%)
 rename examples/demo/wicket/{src/main/java/demoapp/webapp/wicket => common/src/main/java/demoapp/webapp/wicket/common}/ui/custom/WhereInTheWorldPanel.html (100%)
 rename examples/demo/wicket/{src/main/java/demoapp/webapp/wicket => common/src/main/java/demoapp/webapp/wicket/common}/ui/custom/WhereInTheWorldPanel.java (98%)
 rename examples/demo/wicket/{src/main/java/demoapp/webapp/wicket => common/src/main/java/demoapp/webapp/wicket/common}/ui/custom/WhereInTheWorldPanelFactory.java (96%)
 copy examples/demo/wicket/{ => jdo}/pom.xml (68%)
 copy examples/demo/wicket/{src/main/java/demoapp/webapp/wicket/DemoAppWicket.java => jdo/src/main/java/demoapp/webapp/wicket/jdo/DemoAppWicketJdo.java} (86%)
 copy examples/demo/wicket/{ => jdo}/src/main/resources/log4j2-spring.xml (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/fixtures/example.json (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/actions.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/aliasing.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/assertions.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/connectors.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/cookies.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/cypress_api.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/files.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/local_storage.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/location.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/misc.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/navigation.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/network_requests.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/querying.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/spies_stubs_clocks.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/traversal.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/utilities.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/viewport.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/waiting.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/examples/window.spec.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress-scaffolding/integration/typescript/basic.ts (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress.json (100%)
 copy examples/demo/wicket/{ => jdo}/src/test/e2e/cypress/integration/login.ts (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress/plugins/index.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress/support/commands.js (100%)
 rename examples/demo/wicket/{ => jdo}/src/test/e2e/cypress/support/index.js (100%)
 rename examples/demo/wicket/{ => jpa}/pom.xml (75%)
 rename examples/demo/wicket/{src/main/java/demoapp/webapp/wicket/DemoAppWicket.java => jpa/src/main/java/demoapp/webapp/wicket/jpa/DemoAppWicketJpa.java} (75%)
 rename examples/demo/wicket/{src/main => jpa/src}/resources/log4j2-spring.xml (100%)
 delete mode 100644 examples/demo/wicket/src/test/e2e/package-lock.json
 delete mode 100644 examples/demo/wicket/src/test/e2e/package.json
 delete mode 100644 examples/demo/wicket/src/test/e2e/tsconfig.json
 copy valuetypes/asciidoc/persistence/jdo-dn5/src/main/java/org/apache/isis/valuetypes/asciidoc/persistence/jdo/dn5/converters/IsisAsciiDocConverter.java => extensions/core/command-log/jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/IsisModuleExtCommandLogJpa.java (52%)
 copy extensions/core/command-log/{jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java => jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/entities/CommandJpa.java} (84%)
 create mode 100644 extensions/core/command-log/jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/entities/CommandJpaRepository.java
 copy examples/demo/wicket/src/test/e2e/cypress/integration/login.ts => regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeAbstract.java (61%)
 copy examples/demo/wicket/src/test/e2e/cypress/integration/login.ts => regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeConcrete.java (69%)
 copy examples/demo/domain/src/main/java/demoapp/dom/services/extensions/secman/apptenancy/entities/TenantedJdoEntities.java => regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java (59%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/nature/viewmodels/jaxbrefentity/ChildJdo.java => regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ProperElementTypeVm.java (50%)
 copy valuetypes/asciidoc/persistence/{jdo-dn5 => jpa}/pom.xml (78%)
 copy examples/demo/wicket/src/test/e2e/cypress/integration/login.ts => valuetypes/asciidoc/persistence/jpa/src/main/java/org/apache/isis/valuetypes/asciidoc/persistence/jpa/IsisModuleValAsciidocPersistenceJpa.java (67%)
 copy valuetypes/asciidoc/persistence/{jdo-dn5/src/main/java/org/apache/isis/valuetypes/asciidoc/persistence/jdo/dn5 => jpa/src/main/java/org/apache/isis/valuetypes/asciidoc/persistence/jpa}/converters/IsisAsciiDocConverter.java (71%)
 copy valuetypes/markdown/persistence/{jdo-dn5 => jpa}/pom.xml (80%)
 rename examples/demo/wicket/src/test/e2e/cypress/integration/login.ts => valuetypes/markdown/persistence/jpa/src/main/java/org/apache/isis/valuetypes/markdown/persistence/jpa/IsisModuleValMarkdownPersistenceJpa.java (67%)
 copy valuetypes/markdown/persistence/{jdo-dn5/src/main/java/org/apache/isis/valuetypes/markdown/persistence/jdo/dn5 => jpa/src/main/java/org/apache/isis/valuetypes/markdown/persistence/jpa}/converters/IsisMarkdownConverter.java (71%)

[isis] 01/01: ISIS-2614 and ISIS-2609: removes Application.getName ; moves mixin domain events down from API to model

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

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

commit 6764fae603f93023ee6e65ae7c4cfd4713e6c46c
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue May 4 07:20:08 2021 +0100

    ISIS-2614 and ISIS-2609: removes Application.getName ; moves mixin domain events down from API to model
    
    Instead of getName, we use getUsername.
---
 .../isis/applib/services/user/ImpersonateMenu.java |   3 +-
 .../api/permission/ApplicationPermission.java      |  14 +-
 .../secman/api/role/ApplicationRole.java           |  11 -
 .../secman/api/tenancy/ApplicationTenancy.java     |  14 +-
 .../secman/api/user/ApplicationUser.java           | 289 +++++++++++++++++----
 .../secman/model/IsisModuleExtSecmanModel.java     |   5 +-
 ...OrphanedPermissionManager_relocateSelected.java |  28 +-
 .../permission/ApplicationPermission_allow.java    |  16 +-
 .../permission/ApplicationPermission_changing.java |  19 +-
 .../permission/ApplicationPermission_delete.java   |  10 +-
 .../ApplicationPermission_updateRole.java          |  17 +-
 .../dom/permission/ApplicationPermission_veto.java |  14 +-
 .../permission/ApplicationPermission_viewing.java  |  19 +-
 .../dom/role/ApplicationRole_addPermission.java    |  26 +-
 .../model/dom/role/ApplicationRole_addUser.java    |  12 +-
 .../model/dom/role/ApplicationRole_delete.java     |  14 +-
 .../role/ApplicationRole_removePermissions.java    |  18 +-
 .../dom/role/ApplicationRole_removeUsers.java      |  20 +-
 .../role/ApplicationRole_updateDescription.java    |  20 +-
 .../model/dom/role/ApplicationRole_updateName.java |  16 +-
 .../ApplicationUserManager_newDelegateUser.java    |  26 +-
 .../user/ApplicationUserManager_newLocalUser.java  |  24 +-
 .../model/dom/user/ApplicationUser_addRole.java    |  11 +-
 .../model/dom/user/ApplicationUser_delete.java     |  16 +-
 .../model/dom/user/ApplicationUser_duplicate.java  |  21 +-
 .../model/dom/user/ApplicationUser_lock.java       |  13 +-
 .../dom/user/ApplicationUser_removeRoles.java      |  24 +-
 .../dom/user/ApplicationUser_resetPassword.java    |  18 +-
 .../model/dom/user/ApplicationUser_unlock.java     |  12 +-
 .../user/ApplicationUser_updateAccountType.java    |  17 +-
 .../dom/user/ApplicationUser_updateAtPath.java     |  10 +-
 .../user/ApplicationUser_updateEmailAddress.java   |  12 +-
 .../dom/user/ApplicationUser_updateFaxNumber.java  |  12 +-
 .../model/dom/user/ApplicationUser_updateName.java |  13 +-
 .../dom/user/ApplicationUser_updatePassword.java   |  21 +-
 .../user/ApplicationUser_updatePhoneNumber.java    |  15 +-
 .../dom/user/ApplicationUser_updateUsername.java   |  11 +-
 .../menu/ImpersonateMenuAdvisorForSecman.java      |   7 +-
 .../secman/jdo/dom/user/ApplicationUser.java       | 157 ++++-------
 .../dom/user/ApplicationUser.layout.fallback.xml   | 109 +++++---
 .../ApplicationUserManager_newDelegateUser.java    |  22 +-
 .../user/ApplicationUserManager_newLocalUser.java  |  30 +--
 .../jdo/dom/user/ApplicationUserRepository.java    |  46 ++--
 .../secman/jpa/dom/user/ApplicationUser.java       | 170 ++++--------
 .../ApplicationUserManager_newDelegateUser.java    |  20 +-
 .../user/ApplicationUserManager_newLocalUser.java  |  26 +-
 .../jpa/dom/user/ApplicationUserRepository.java    |  46 ++--
 .../secman/shiro/PrincipalForApplicationUser.java  |  30 +--
 48 files changed, 861 insertions(+), 663 deletions(-)

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 87ea661..395034f 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
@@ -3,6 +3,7 @@ package org.apache.isis.applib.services.user;
 import java.util.Collections;
 import java.util.List;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.apache.isis.applib.IsisModuleApplib;
@@ -114,7 +115,7 @@ public class ImpersonateMenu {
             final String userName,
             final List<String> roleNames) {
 
-        this.userService.impersonateUser(userName, roleNames);
+        this.userService.impersonateUser(userName, roleNames != null ? roleNames : Collections.emptyList());
         this.messageService.informUser("Now impersonating " + userName);
     }
     public boolean hideImpersonateWithRoles() {
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermission.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermission.java
index 823ae5c..2baae35 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermission.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermission.java
@@ -40,7 +40,7 @@ import lombok.val;
  *
  * <p>
  *     Each permission has a {@link #getRule() rule} and a {@link #getMode() mode}.  The
- *     {@link ApplicationPermissionRule rule} determines whether the permission 
+ *     {@link ApplicationPermissionRule rule} determines whether the permission
  *     {@link ApplicationPermissionRule#ALLOW grants}
  *     access to the feature or {@link ApplicationPermissionRule#VETO veto}es access
  *     to it.  The {@link ApplicationPermissionMode mode} indicates whether
@@ -72,16 +72,6 @@ public interface ApplicationPermission {
 
     public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationPermission, T> {}
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermission, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission> {}
-
-    public static class AllowDomainEvent extends ActionDomainEvent {}
-    public static class UpdateRoleDomainEvent extends ActionDomainEvent {}
-    public static class VetoDomainEvent extends ActionDomainEvent {}
-    public static class DeleteDomainEvent extends ActionDomainEvent {}
-    public static class ChangingDomainEvent extends ActionDomainEvent {}
-    public static class ViewingDomainEvent extends ActionDomainEvent {}
-
-    public static class RelocateNamespaceDomainEvent extends ActionDomainEvent {}
 
     // -- MODEL
 
@@ -130,7 +120,7 @@ public interface ApplicationPermission {
     @Property
     @PropertyLayout(
             hidden=Where.REFERENCES_PARENT,
-            fieldSetId="Role", 
+            fieldSetId="Role",
             sequence = "1")
     default ApplicationRole getRole() {
         throw _Exceptions.unsupportedOperation("please implement me");
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRole.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRole.java
index 6c30ef0..988bb28 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRole.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRole.java
@@ -35,17 +35,6 @@ public interface ApplicationRole {
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationRole, T> {}
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole> {}
 
-    public static class AddUserDomainEvent extends ActionDomainEvent {}
-    public static class RemoveUserDomainEvent extends ActionDomainEvent {}
-    
-    public static class AddPermissionDomainEvent extends ActionDomainEvent {}
-    public static class RemovePermissionDomainEvent extends ActionDomainEvent {}
-
-    public static class DeleteDomainEvent extends ActionDomainEvent {}
-
-    public static class UpdateDescriptionDomainEvent extends ActionDomainEvent {}
-    public static class UpdateNameDomainEvent extends ActionDomainEvent {}
-
     // -- MODEL
 
     /**
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancy.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancy.java
index c39f3f5..ed209ea 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancy.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancy.java
@@ -35,13 +35,13 @@ public interface ApplicationTenancy {
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationTenancy, T> {}
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
 
-    public static class AddUserDomainEvent extends ActionDomainEvent {}
-    public static class RemoveUserDomainEvent extends ActionDomainEvent {}
-    public static class AddChildDomainEvent extends ActionDomainEvent {}
-    public static class DeleteDomainEvent extends ActionDomainEvent {}
-    public static class RemoveChildDomainEvent extends ActionDomainEvent {}
-    public static class UpdateNameDomainEvent extends ActionDomainEvent {}
-    public static class UpdateParentDomainEvent extends ActionDomainEvent {}
+    public static class AddUserDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    public static class RemoveUserDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    public static class AddChildDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    public static class DeleteDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    public static class RemoveChildDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    public static class UpdateNameDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    public static class UpdateParentDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
 
     // -- MODEL
 
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java
index f4d227d..3e95d2c 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java
@@ -20,12 +20,27 @@ package org.apache.isis.extensions.secman.api.user;
 
 import java.util.Set;
 
+import javax.inject.Inject;
+
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+
+import org.apache.isis.applib.annotation.Collection;
+import org.apache.isis.applib.annotation.CollectionLayout;
+import org.apache.isis.applib.annotation.Editing;
+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.Where;
 import org.apache.isis.applib.mixins.security.HasUsername;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValueSet;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.tenancy.HasAtPath;
 
+import lombok.RequiredArgsConstructor;
+
 /**
  * @since 2.0 {@index}
  */
@@ -33,93 +48,267 @@ public interface ApplicationUser extends HasUsername, HasAtPath {
 
     // -- CONSTANTS
 
-    public static final int MAX_LENGTH_USERNAME = 120;
-    public static final int MAX_LENGTH_FAMILY_NAME = 120;
-    public static final int MAX_LENGTH_GIVEN_NAME = 120;
-    public static final int MAX_LENGTH_KNOWN_AS = 120;
-    public static final int MAX_LENGTH_EMAIL_ADDRESS = 120;
-    public static final int MAX_LENGTH_PHONE_NUMBER = 120;
+    int MAX_LENGTH_USERNAME = 120;
+    int MAX_LENGTH_FAMILY_NAME = 120;
+    int MAX_LENGTH_GIVEN_NAME = 120;
+    int MAX_LENGTH_KNOWN_AS = 120;
+    int MAX_LENGTH_EMAIL_ADDRESS = 120;
+    int MAX_LENGTH_PHONE_NUMBER = 120;
+    int MAX_LENGTH_AT_PATH = 254;
 
     // -- DOMAIN EVENTS
 
-    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationUser, T> {}
-    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationUser, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser> {}
-
-    public static class AddRoleDomainEvent extends ActionDomainEvent {}
-    public static class UpdateAtPathDomainEvent extends ActionDomainEvent {}
-    public static class UpdateUsernameDomainEvent extends ActionDomainEvent {}
-    public static class UpdateNameDomainEvent extends ActionDomainEvent {}
-    public static class UpdateEmailAddressDomainEvent extends ActionDomainEvent {}
-    public static class UpdatePhoneNumberDomainEvent extends ActionDomainEvent {}
-    public static class UpdateFaxNumberDomainEvent extends ActionDomainEvent {}
-    public static class UpdateAccountTypeDomainEvent extends ActionDomainEvent {}
-    public static class UnlockDomainEvent extends ActionDomainEvent {}
-    public static class LockDomainEvent extends ActionDomainEvent {}
-    public static class UpdatePasswordDomainEvent extends ActionDomainEvent {}
-    public static class ResetPasswordDomainEvent extends ActionDomainEvent {}
-    public static class RemoveRoleDomainEvent extends ActionDomainEvent {}
-    public static class DeleteDomainEvent extends ActionDomainEvent {}
-    public static class NewDelegateUserDomainEvent extends ActionDomainEvent {}
-    public static class NewLocalUserDomainEvent extends ActionDomainEvent {}
-    public static class UserDuplicateDomainEvent extends ActionDomainEvent {}
+    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationUser, T> {}
+    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationUser, T> {}
 
     // -- MODEL
 
-    /**
-     * having a title() method (rather than using @Title annotation) is necessary as a workaround to be able to use
-     * wrapperFactory#unwrap(...) method, which is otherwise broken in Isis 1.6.0
-     */
     default String title() {
-        return getName();
+        final StringBuilder buf = new StringBuilder();
+        if(getFamilyName() != null) {
+            if(getKnownAs() != null) {
+                buf.append(getKnownAs());
+            } else {
+                buf.append(getGivenName());
+            }
+            buf.append(' ')
+                    .append(getFamilyName())
+                    .append(" (").append(getUsername()).append(')');
+        } else {
+            buf.append(getUsername());
+        }
+        return buf.toString();
     }
 
     default String iconName() {
         return getStatus().isEnabled() ? "enabled" : "disabled";
     }
 
-    String getName();
 
-    String getEncryptedPassword();
-
-    AccountType getAccountType();
-    void setAccountType(AccountType accountType);
-
-    ApplicationPermissionValueSet getPermissionSet();
+    // -- username (property)
 
-    Set<? extends ApplicationRole> getRoles();
+    class UsernameDomainEvent extends PropertyDomainEvent<String> {}
 
-    ApplicationUserStatus getStatus();
-    void setStatus(ApplicationUserStatus disabled);
+    @Property(
+            domainEvent = UsernameDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_USERNAME
+    )
+    @PropertyLayout(
+            hidden=Where.PARENTED_TABLES,
+            fieldSetId="identity",
+            sequence = "1")
+    @Override
+    String getUsername();
+    void setUsername(String username);
 
-    void setAtPath(String atPath);
 
-    String getEmailAddress();
-    void setEmailAddress(String emailAddress);
+    // -- familyName (property)
 
-    String getFaxNumber();
-    void setFaxNumber(String faxNumber);
+    class FamilyNameDomainEvent extends PropertyDomainEvent<String> {}
 
+    @Property(
+            domainEvent = FamilyNameDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_FAMILY_NAME
+    )
+    @PropertyLayout(
+            hidden=Where.ALL_TABLES,
+            fieldSetId="Name",
+            sequence = "2.1")
     String getFamilyName();
     void setFamilyName(String familyName);
 
+
+    // -- givenName (property)
+
+    class GivenNameDomainEvent extends PropertyDomainEvent<String> {}
+
+    @Property(
+            domainEvent = GivenNameDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_KNOWN_AS
+    )
+    @PropertyLayout(
+            hidden=Where.ALL_TABLES,
+            fieldSetId="Name",
+            sequence = "2.2")
     String getGivenName();
     void setGivenName(String givenName);
 
+
+    // -- knownAs (property)
+
+    class KnownAsDomainEvent extends PropertyDomainEvent<String> {}
+
+    @Property(
+            domainEvent = KnownAsDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_KNOWN_AS
+    )
+    @PropertyLayout(
+            hidden=Where.ALL_TABLES,
+            fieldSetId="Name",
+            sequence = "2.3")
     String getKnownAs();
     void setKnownAs(String knownAs);
 
+
+    // -- emailAddress (property)
+
+    class EmailAddressDomainEvent extends PropertyDomainEvent<String> {}
+
+    @Property(
+            domainEvent = EmailAddressDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_EMAIL_ADDRESS
+    )
+    @PropertyLayout(fieldSetId="Contact Details", sequence = "3.1")
+    String getEmailAddress();
+    void setEmailAddress(String emailAddress);
+
+
+    // -- phoneNumber (property)
+
+    class PhoneNumberDomainEvent extends PropertyDomainEvent<String> {}
+
+    @Property(
+            domainEvent = PhoneNumberDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_PHONE_NUMBER
+    )
+    @PropertyLayout(fieldSetId="Contact Details", sequence = "3.2")
     String getPhoneNumber();
     void setPhoneNumber(String phoneNumber);
 
-    void setUsername(String username);
 
+    // -- faxNumber (property)
+
+    class FaxNumberDomainEvent extends PropertyDomainEvent<String> {}
+
+    @Property(
+            domainEvent = FaxNumberDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_PHONE_NUMBER
+    )
+    @PropertyLayout(
+            hidden=Where.PARENTED_TABLES,
+            fieldSetId="Contact Details",
+            sequence = "3.3")
+    String getFaxNumber();
+    void setFaxNumber(String faxNumber);
+
+
+    // -- atPath (property)
+
+    class AtPathDomainEvent extends PropertyDomainEvent<String> {}
+
+    @Property(
+            domainEvent = AtPathDomainEvent.class,
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_AT_PATH
+    )
+    @PropertyLayout(fieldSetId="atPath", sequence = "3.4")
+    @Override
+    String getAtPath();
+    void setAtPath(String atPath);
+
+    // -- accountType (property)
+
+    class AccountTypeDomainEvent extends PropertyDomainEvent<AccountType> {}
+
+    @Property(
+            domainEvent = AccountTypeDomainEvent.class,
+            editing = Editing.DISABLED
+    )
+    @PropertyLayout(fieldSetId="Status", sequence = "3")
+    AccountType getAccountType();
+    void setAccountType(AccountType accountType);
+
+
+    // -- status (property)
+
+    class StatusDomainEvent extends PropertyDomainEvent<ApplicationUserStatus> {}
+
+    @Property(
+            domainEvent = StatusDomainEvent.class,
+            editing = Editing.DISABLED
+    )
+    @PropertyLayout(fieldSetId="Status", sequence = "4")
+    ApplicationUserStatus getStatus();
+    void setStatus(ApplicationUserStatus disabled);
+
+
+    // -- encryptedPassword (hidden property)
+
+    @PropertyLayout(hidden=Where.EVERYWHERE)
+    String getEncryptedPassword();
     void setEncryptedPassword(String encryptedPassword);
 
-    boolean isForSelfOrRunAsAdministrator();
 
-    boolean isHasPassword();
 
+    // -- hasPassword (derived property)
+
+    class HasPasswordDomainEvent extends PropertyDomainEvent<Boolean> {}
+
+    @Property(
+            domainEvent = HasPasswordDomainEvent.class,
+            editing = Editing.DISABLED
+    )
+    @PropertyLayout(fieldSetId="Status", sequence = "4")
+    default boolean isHasPassword() {
+        return _Strings.isNotEmpty(getEncryptedPassword());
+    }
+
+    @Component
+    @RequiredArgsConstructor(onConstructor_ = {@Inject})
+    class HasPasswordAdvisor {
+
+        final org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<?> applicationUserRepository;
+
+        @EventListener(org.apache.isis.extensions.secman.api.user.ApplicationUser.HasPasswordDomainEvent.class)
+        public void advise(org.apache.isis.extensions.secman.api.user.ApplicationUser.HasPasswordDomainEvent ev) {
+            switch(ev.getEventPhase()) {
+                case HIDE:
+                    if(! applicationUserRepository.isPasswordFeatureEnabled(ev.getSource())) {
+                        ev.hide();
+                    }
+                    break;
+            }
+        }
+    }
+
+
+
+
+
+    // -- roles (collection)
+
+
+    class RolesDomainEvent extends CollectionDomainEvent<ApplicationRole> {}
+
+    @Collection(
+            domainEvent = RolesDomainEvent.class
+    )
+    @CollectionLayout(
+            defaultView="table",
+            sequence = "20")
+    Set<? extends ApplicationRole> getRoles();
+
+
+
+
+    /**
+     * Short-term (request-scoped) caching.
+     * @return
+     */
+    @Programmatic
+    ApplicationPermissionValueSet getPermissionSet();
+
+    @Programmatic
+    boolean isForSelfOrRunAsAdministrator();
+
+    @Programmatic
     default boolean isLocalAccount() {
         return getAccountType() == AccountType.LOCAL;
     }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/IsisModuleExtSecmanModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/IsisModuleExtSecmanModel.java
index 362f968..1b92eaa 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/IsisModuleExtSecmanModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/IsisModuleExtSecmanModel.java
@@ -22,6 +22,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.model.dom.feature.ApplicationFeatureViewModels;
 import org.apache.isis.extensions.secman.model.dom.feature.ApplicationNamespace;
 import org.apache.isis.extensions.secman.model.dom.feature.ApplicationType;
@@ -98,7 +99,9 @@ import org.apache.isis.extensions.secman.model.spiimpl.TableColumnHidingService;
         ApplicationTenancyMenu.class,
         ApplicationUserMenu.class,
 
-        //ImpersonateMenuAdvisorForSecman.class, //not activated by default yet
+        ApplicationUser.HasPasswordAdvisor.class,
+
+        ImpersonateMenuAdvisorForSecman.class, //not activated by default yet
         MeService.class,
 
         // @Component
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java
index bf86949..dca9c58 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java
@@ -32,30 +32,33 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.appfeat.ApplicationFeature;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.RelocateNamespaceDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationOrphanedPermissionManager_relocateSelected.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @Action(
         associateWith = "orphanedPermissions",
-        domainEvent = RelocateNamespaceDomainEvent.class, 
+        domainEvent = ActionDomainEvent.class,
         semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
 @ActionLayout(describedAs = "for the selected permissions renames the namespace")
 @RequiredArgsConstructor
 public class ApplicationOrphanedPermissionManager_relocateSelected {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationOrphanedPermissionManager_relocateSelected> {}
+
     @Inject private ApplicationFeatureRepository featureRepository;
-    
+
     private final ApplicationOrphanedPermissionManager target;
-    
+
     public ApplicationOrphanedPermissionManager act(
             final Collection<ApplicationPermission> permissions,
-            
+
             @Parameter(optionality = Optionality.MANDATORY)
             final String targetNamespace) {
-        
+
         permissions.forEach(perm->relocate(perm, targetNamespace));
         return target;
     }
@@ -65,20 +68,19 @@ public class ApplicationOrphanedPermissionManager_relocateSelected {
                     .map(ApplicationFeature::getFullyQualifiedName)
                     .collect(Collectors.toCollection(TreeSet::new));
     }
-    
+
     private void relocate(
-            final ApplicationPermission permission, 
+            final ApplicationPermission permission,
             final String targetNamespace) {
-        
+
         val appFeatureId = ApplicationFeatureId.newFeature(
-                permission.getFeatureSort(), 
+                permission.getFeatureSort(),
                 permission.getFeatureFqn());
-        
+
         val relocatedFqn = appFeatureId
                 .withNamespace(targetNamespace)
                 .getFullyQualifiedName();
-        
+
         permission.setFeatureFqn(relocatedFqn);
     }
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java
index 8dbe48b..79e6882 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java
@@ -19,19 +19,28 @@
 package org.apache.isis.extensions.secman.model.dom.permission;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.AllowDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationPermission_allow.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = AllowDomainEvent.class, associateWith = "rule")
+@Action(
+        domainEvent = ApplicationPermission_allow.ActionDomainEvent.class,
+        associateWith = "rule"
+)
+@ActionLayout(
+        sequence = "1"
+)
 @RequiredArgsConstructor
 public class ApplicationPermission_allow {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_allow> {}
+
     private final ApplicationPermission target;
 
-    //@PropertyLayout(group = "Rule", sequence = "1")
     public ApplicationPermission act() {
         target.setRule(ApplicationPermissionRule.ALLOW);
         return target;
@@ -40,5 +49,4 @@ public class ApplicationPermission_allow {
     public String disableAct() {
         return target.getRule() == ApplicationPermissionRule.ALLOW? "Rule is already set to ALLOW": null;
     }
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java
index b5e27f0..7f2e611 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java
@@ -19,27 +19,34 @@
 package org.apache.isis.extensions.secman.model.dom.permission;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.ChangingDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationPermission_changing.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = ChangingDomainEvent.class, associateWith = "mode")
+@Action(
+        domainEvent = ApplicationPermission_changing.ActionDomainEvent.class,
+        associateWith = "mode")
+@ActionLayout(
+        sequence = "2", promptStyle = PromptStyle.INLINE
+)
 @RequiredArgsConstructor
 public class ApplicationPermission_changing {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_changing> {}
+
     private final ApplicationPermission target;
 
-    //@PropertyLayout(group = "Mode", sequence = "2")
     public ApplicationPermission act() {
         target.setMode(ApplicationPermissionMode.CHANGING);
         return target;
     }
-    
+
     public String disableAct() {
         return target.getMode() == ApplicationPermissionMode.CHANGING ? "Mode is already set to CHANGING": null;
     }
-    
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java
index 8ffda8a..b56f729 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java
@@ -23,19 +23,22 @@ import javax.inject.Inject;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.DeleteDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationPermission_delete.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @Action(
-        domainEvent = DeleteDomainEvent.class, 
+        domainEvent = ApplicationPermission_delete.ActionDomainEvent.class,
         semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
 @RequiredArgsConstructor
 public class ApplicationPermission_delete {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_delete> {}
+
     @Inject private RepositoryService repository;
 
     private final ApplicationPermission target;
@@ -45,5 +48,4 @@ public class ApplicationPermission_delete {
         repository.remove(target);
         return owningRole;
     }
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_updateRole.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_updateRole.java
index ab24095..20653a3 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_updateRole.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_updateRole.java
@@ -23,24 +23,32 @@ import java.util.Collection;
 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.PromptStyle;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.UpdateRoleDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationPermission_updateRole.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateRoleDomainEvent.class, 
+        domainEvent = ActionDomainEvent.class,
         associateWith = "role")
+@ActionLayout(
+        sequence = "1",
+        promptStyle = PromptStyle.INLINE_AS_IF_EDIT)
 @RequiredArgsConstructor
 public class ApplicationPermission_updateRole {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_updateRole> {}
+
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    
+
     private final ApplicationPermission target;
-    
+
     @MemberSupport
     public ApplicationPermission act(final ApplicationRole applicationRole) {
         target.setRole(applicationRole);
@@ -56,5 +64,4 @@ public class ApplicationPermission_updateRole {
     public Collection<? extends ApplicationRole> choices0Act() {
         return applicationRoleRepository.allRoles();
     }
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java
index fd404a0..4ce7ffe 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java
@@ -19,21 +19,27 @@
 package org.apache.isis.extensions.secman.model.dom.permission;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.VetoDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationPermission_veto.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = VetoDomainEvent.class, 
+        domainEvent = ApplicationPermission_veto.ActionDomainEvent.class,
         associateWith = "rule")
+@ActionLayout(
+        sequence = "2"
+)
 @RequiredArgsConstructor
 public class ApplicationPermission_veto {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_veto> {}
+
     private final ApplicationPermission target;
 
-    //@PropertyLayout(group = "Rule", sequence = "1")
     public ApplicationPermission act() {
         target.setRule(ApplicationPermissionRule.VETO);
         return target;
@@ -41,6 +47,4 @@ public class ApplicationPermission_veto {
     public String disableAct() {
         return target.getRule() == ApplicationPermissionRule.VETO? "Rule is already set to VETO": null;
     }
-    
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java
index 83bbbba..458638c 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java
@@ -19,29 +19,34 @@
 package org.apache.isis.extensions.secman.model.dom.permission;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.ViewingDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.permission.ApplicationPermission_viewing.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = ViewingDomainEvent.class, 
+        domainEvent = ApplicationPermission_viewing.ActionDomainEvent.class,
         associateWith = "mode")
+@ActionLayout(
+        sequence = "1", promptStyle = PromptStyle.INLINE
+)
 @RequiredArgsConstructor
 public class ApplicationPermission_viewing {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_viewing> {}
+
     private final ApplicationPermission target;
-    
-    //@PropertyLayout(group = "Mode", sequence = "1")
+
     public ApplicationPermission act() {
         target.setMode(ApplicationPermissionMode.VIEWING);
         return target;
     }
-    
+
     public String disableAct() {
         return target.getMode() == ApplicationPermissionMode.VIEWING ? "Mode is already set to VIEWING": null;
     }
-    
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java
index 9ab3053..51cee50 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java
@@ -30,12 +30,13 @@ import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.services.appfeat.ApplicationFeature;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_addPermission.ActionDomainEvent;
 import org.apache.isis.extensions.secman.model.dom.feature.ApplicationFeatureChoices;
 
 import lombok.RequiredArgsConstructor;
@@ -43,7 +44,7 @@ import lombok.Value;
 import lombok.experimental.Accessors;
 
 @Action(
-        domainEvent = AddPermissionDomainEvent.class, 
+        domainEvent = ApplicationRole_addPermission.ActionDomainEvent.class,
         associateWith = "permissions")
 @ActionLayout(
 		named="Add",
@@ -51,13 +52,15 @@ import lombok.experimental.Accessors;
 		promptStyle = PromptStyle.DIALOG_MODAL)
 @RequiredArgsConstructor
 public class ApplicationRole_addPermission {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_addPermission> {}
+
     @Inject private ApplicationFeatureRepository featureRepository;
     @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
-    
+
     private final ApplicationRole target;
-    
-    @Value @Accessors(fluent = true)           
+
+    @Value @Accessors(fluent = true)
     public static class Parameters {
         ApplicationPermissionRule rule; // ALLOW/VETO
         ApplicationPermissionMode mode; // r/w
@@ -69,21 +72,19 @@ public class ApplicationRole_addPermission {
      * {@link ApplicationFeature feature}.
      */
     public ApplicationRole act(
-            
+
             @Parameter(optionality = Optionality.MANDATORY)
-            @ParameterLayout(named="Rule")
             final ApplicationPermissionRule rule,
-            
+
             @Parameter(optionality = Optionality.MANDATORY)
-            @ParameterLayout(named="Mode")
             final ApplicationPermissionMode mode,
-            
+
             @Parameter(optionality = Optionality.MANDATORY)
             @ParameterLayout(
                     named = "Feature",
                     describedAs = ApplicationFeatureChoices.DESCRIBED_AS)
             final ApplicationFeatureChoices.AppFeat feature) {
-        
+
         applicationPermissionRepository.newPermission(target, rule, mode, feature.getFeatureId());
         return target;
     }
@@ -104,5 +105,4 @@ public class ApplicationRole_addPermission {
             final @MinLength(3) String search) {
         return ApplicationFeatureChoices.autoCompleteFeature(featureRepository, search);
     }
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addUser.java
index 6e98cd7..608fa07 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addUser.java
@@ -27,8 +27,9 @@ 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.commons.internal.collections._Lists;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddUserDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_addUser.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
@@ -36,15 +37,17 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = AddUserDomainEvent.class, 
+        domainEvent = ApplicationRole_addUser.ActionDomainEvent.class,
         associateWith = "users")
 @ActionLayout(named="Add", sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationRole_addUser {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_addUser> {}
+
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
     private final ApplicationRole target;
 
     @MemberSupport
@@ -60,4 +63,5 @@ public class ApplicationRole_addUser {
         list.removeAll(applicationUserRepository.findByRole(target));
         return list;
     }
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_delete.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_delete.java
index 98818d5..57933e8 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_delete.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_delete.java
@@ -26,23 +26,27 @@ 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.api.IsisModuleExtSecmanApi;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.DeleteDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_delete.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = DeleteDomainEvent.class, 
+        domainEvent = ApplicationRole_delete.ActionDomainEvent.class,
         semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationRole_delete {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_delete> {}
+
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    
+
     private final ApplicationRole holder;
-    
+
     @MemberSupport
     public Collection<? extends ApplicationRole> act() {
         applicationRoleRepository.deleteRole(holder);
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermissions.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermissions.java
index 921641d..f60f353 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermissions.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermissions.java
@@ -30,16 +30,17 @@ import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.RemovePermissionDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_removePermissions.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = RemovePermissionDomainEvent.class, 
+        domainEvent = ApplicationRole_removePermissions.ActionDomainEvent.class,
         associateWith = "permissions")
 @ActionLayout(
 		named="Remove",
@@ -48,20 +49,22 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationRole_removePermissions {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_removePermissions> {}
+
     @Inject private MessageService messageService;
     @Inject private SecmanConfiguration configBean;
     @Inject private RepositoryService repository;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    
+
     private final ApplicationRole target;
 
     @MemberSupport
     public ApplicationRole act(Collection<ApplicationPermission> permissions) {
-        
+
         _NullSafe.stream(permissions)
         .filter(this::canRemove)
         .forEach(repository::remove);
-        
+
         return target;
     }
 
@@ -69,13 +72,12 @@ public class ApplicationRole_removePermissions {
         if(!Objects.equals(permission.getRole(), target)) {
             return false;
         }
-        if(applicationRoleRepository.isAdminRole(target) 
+        if(applicationRoleRepository.isAdminRole(target)
                 && configBean.isStickyAdminNamespace(permission.getFeatureFqn())) {
-            
+
             messageService.warnUser("Cannot remove top-level namespace permissions for the admin role.");
             return false;
         }
         return true;
     }
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUsers.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUsers.java
index 7e62b13..4045256 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUsers.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUsers.java
@@ -27,8 +27,9 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.RemoveUserDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_removeUsers.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
@@ -36,37 +37,36 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = RemoveUserDomainEvent.class,
+        domainEvent = ApplicationRole_removeUsers.ActionDomainEvent.class,
         associateWith = "users")
 @ActionLayout(named="Remove", sequence = "2")
 @RequiredArgsConstructor
 public class ApplicationRole_removeUsers {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_removeUsers> {}
+
     @Inject private MessageService messageService;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
     private final ApplicationRole target;
 
     @MemberSupport
     public ApplicationRole act(Collection<ApplicationUser> users) {
-        
+
         _NullSafe.stream(users)
         .filter(this::canRemove)
         .forEach(user->applicationRoleRepository.removeRoleFromUser(target, user));
 
         return target;
     }
-    
+
     public boolean canRemove(ApplicationUser applicationUser) {
-        if(applicationUserRepository.isAdminUser(applicationUser) 
+        if(applicationUserRepository.isAdminUser(applicationUser)
                 && applicationRoleRepository.isAdminRole(target)) {
             messageService.warnUser("Cannot remove admin user from the admin role.");
             return false;
         }
         return true;
     }
-    
-    
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java
index 0ba4db7..5f815ad 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java
@@ -24,21 +24,25 @@ 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.ParameterLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.types.DescriptionType;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.UpdateDescriptionDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_updateDescription.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateDescriptionDomainEvent.class, 
+        domainEvent = ApplicationRole_updateDescription.ActionDomainEvent.class,
         associateWith = "description")
-@ActionLayout(sequence = "1")
+@ActionLayout(sequence = "1", promptStyle = PromptStyle.INLINE_AS_IF_EDIT)
 @RequiredArgsConstructor
 public class ApplicationRole_updateDescription {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_updateDescription> {}
+
     private final ApplicationRole target;
-    
+
     @MemberSupport
     public ApplicationRole act(
             @Parameter(
@@ -46,10 +50,10 @@ public class ApplicationRole_updateDescription {
                     optionality = Optionality.OPTIONAL
                     )
             @ParameterLayout(
-                    named="Description", 
+                    named="Description",
                     typicalLength=ApplicationRole.TYPICAL_LENGTH_DESCRIPTION)
             final String description) {
-        
+
         target.setDescription(description);
         return target;
     }
@@ -58,6 +62,4 @@ public class ApplicationRole_updateDescription {
     public String default0Act() {
         return target.getDescription();
     }
-
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java
index 3b805b9..941c9cc 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java
@@ -22,25 +22,28 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.UpdateNameDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.role.ApplicationRole_updateName.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateNameDomainEvent.class, 
+        domainEvent = ApplicationRole_updateName.ActionDomainEvent.class,
         associateWith = "name")
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationRole_updateName {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_updateName> {}
+
     private final ApplicationRole target;
-    
+
     public ApplicationRole act(
-            @Parameter(maxLength = ApplicationRole.MAX_LENGTH_NAME) 
+            @Parameter(maxLength = ApplicationRole.MAX_LENGTH_NAME)
             @ParameterLayout(named="Name", typicalLength = ApplicationRole.TYPICAL_LENGTH_NAME)
             final String name) {
-        
+
         target.setName(name);
         return target;
     }
@@ -48,5 +51,4 @@ public class ApplicationRole_updateName {
     public String default0Act() {
         return target.getName();
     }
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
index 30395b2..f5991ad 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
@@ -21,6 +21,7 @@ package org.apache.isis.extensions.secman.model.dom.user;
 import javax.inject.Inject;
 
 import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.SecurityRealmCharacteristic;
 import org.apache.isis.extensions.secman.api.SecurityRealmService;
@@ -34,16 +35,19 @@ import lombok.val;
 
 /**
  * @apiNote This mixin requires concrete implementations associated with JPA and JDO,
- * since action's type parameters are inspected for their compile time types 
- * and the ApplicationRole here is just an interface that the framework has not much 
+ * since action's type parameters are inspected for their compile time types
+ * and the ApplicationRole here is just an interface that the framework has not much
  * meta-model information to derive UI behavior from.
- * 
+ *
  * @implNote due to current limitations, both the main and its supporting methods have to be
- * overridden with the concrete subclasses. 
- * 
+ * overridden with the concrete subclasses.
+ *
  */
 public abstract class ApplicationUserManager_newDelegateUser<R extends ApplicationRole> {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUserManager_newDelegateUser> {}
+
+    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
     @Inject private ApplicationRoleRepository<R> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
@@ -54,7 +58,7 @@ public abstract class ApplicationUserManager_newDelegateUser<R extends Applicati
           final String username,
           final R initialRole,
           final Boolean enabled) {
-        
+
         final ApplicationUser user = applicationUserRepository
                 .newDelegateUser(username, ApplicationUserStatus.parse(enabled));
 
@@ -64,7 +68,7 @@ public abstract class ApplicationUserManager_newDelegateUser<R extends Applicati
         repository.persist(user);
         return user;
     }
-    
+
     protected boolean doHide() {
         return hasNoDelegateAuthenticationRealm();
     }
@@ -74,12 +78,12 @@ public abstract class ApplicationUserManager_newDelegateUser<R extends Applicati
                 .findByNameCached(configBean.getRegularUserRoleName())
                 .orElse(null);
     }
-    
+
     // -- HELPER
-    
+
     private boolean hasNoDelegateAuthenticationRealm() {
         val realm = securityRealmService.getCurrentRealm();
-        return realm == null 
+        return realm == null
                 || !realm.getCharacteristics()
                     .contains(SecurityRealmCharacteristic.DELEGATING);
     }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
index b440c60..05281b0 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
@@ -25,6 +25,7 @@ import javax.inject.Inject;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.Password;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
@@ -34,22 +35,24 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
 /**
  * @apiNote This mixin requires concrete implementations associated with JPA and JDO,
- * since action's type parameters are inspected for their compile time types 
- * and the ApplicationRole here is just an interface that the framework has not much 
+ * since action's type parameters are inspected for their compile time types
+ * and the ApplicationRole here is just an interface that the framework has not much
  * meta-model information to derive UI behavior from.
- * 
+ *
  * @implNote due to current limitations, both the main and its supporting methods have to be
- * overridden with the concrete subclasses. 
- * 
+ * overridden with the concrete subclasses.
+ *
  */
 public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationRole> {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUserManager_newLocalUser> {}
+
     @Inject private ApplicationRoleRepository<R> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
     @Inject private FactoryService factory;
     @Inject private RepositoryService repository;
-    
+
     protected ApplicationUser doAct(
             final String username,
             final Password password,
@@ -57,7 +60,7 @@ public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationR
             final R initialRole,
             final Boolean enabled,
             final String emailAddress) {
-        
+
         ApplicationUser user = applicationUserRepository.findByUsername(username).orElse(null);
         if (user == null) {
             user = applicationUserRepository
@@ -81,19 +84,18 @@ public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationR
             final R initialRole,
             final Boolean enabled,
             final String emailAddress) {
-        
+
         if (!Objects.equals(newPassword, newPasswordRepeat)) {
             return "Passwords do not match";
         }
 
         return null;
     }
-    
+
     protected R doDefault3() {
         return applicationRoleRepository
                 .findByNameCached(configBean.getRegularUserRoleName())
                 .orElse(null);
     }
-   
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_addRole.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_addRole.java
index f99b494..d5ff1dc 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_addRole.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_addRole.java
@@ -25,23 +25,26 @@ import javax.inject.Inject;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.commons.internal.collections._Sets;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.AddRoleDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_addRole.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @Action(
-        domainEvent = AddRoleDomainEvent.class, 
+        domainEvent = ApplicationUser_addRole.ActionDomainEvent.class,
         associateWith = "roles")
 @ActionLayout(named="Add", sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationUser_addRole {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_addRole> {}
+
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    
+
     private final ApplicationUser target;
 
     public ApplicationUser act(final ApplicationRole role) {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_delete.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_delete.java
index 4868fce..0954621 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_delete.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_delete.java
@@ -27,22 +27,26 @@ 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.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.DeleteDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_delete.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = DeleteDomainEvent.class,
-        semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
-@ActionLayout(sequence = "1")
+        domainEvent = ApplicationUser_delete.ActionDomainEvent.class,
+        semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE,
+        associateWith = "username")
+@ActionLayout(sequence = "2", position = ActionLayout.Position.PANEL)
 @RequiredArgsConstructor
 public class ApplicationUser_delete {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_delete> {}
+
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private RepositoryService repository;
-    
+
     private final ApplicationUser target;
 
     @MemberSupport
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_duplicate.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_duplicate.java
index a9226f9..2cd40c9 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_duplicate.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_duplicate.java
@@ -21,24 +21,30 @@ package org.apache.isis.extensions.secman.model.dom.user;
 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.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UserDuplicateDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_duplicate.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UserDuplicateDomainEvent.class 
+        domainEvent = ApplicationUser_duplicate.ActionDomainEvent.class,
+        associateWith = "username"
         )
+@ActionLayout(sequence = "1", position = ActionLayout.Position.PANEL)
 @RequiredArgsConstructor
 public class ApplicationUser_duplicate {
 
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_duplicate> {}
+
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
 
@@ -50,19 +56,18 @@ public class ApplicationUser_duplicate {
             final String username,
             @Parameter(optionality = Optionality.OPTIONAL)
             final String emailAddress) {
-        
+
         return applicationUserRepository
                 .newUser(username, target.getAccountType(), user->{
-        
+
                     user.setStatus(ApplicationUserStatus.DISABLED);
                     user.setEmailAddress(emailAddress);
-        
+
                     for (ApplicationRole role : target.getRoles()) {
                         applicationRoleRepository.addRoleToUser(role, user);
                     }
-                    
+
                 });
-        
+
     }
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_lock.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_lock.java
index 3b0b2c2..3ecd459 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_lock.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_lock.java
@@ -23,24 +23,27 @@ 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.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.LockDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_lock.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = LockDomainEvent.class, 
+        domainEvent = ApplicationUser_lock.ActionDomainEvent.class,
         associateWith = "status")
 @ActionLayout(named="Disable", sequence = "2")
 @RequiredArgsConstructor
 public class ApplicationUser_lock {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_lock> {}
+
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
-    
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -48,7 +51,7 @@ public class ApplicationUser_lock {
         target.setStatus(ApplicationUserStatus.DISABLED);
         return target;
     }
-    
+
     @MemberSupport
     public String disableAct() {
         if(applicationUserRepository.isAdminUser(target)) {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRoles.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRoles.java
index d009da1..dd13f3f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRoles.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRoles.java
@@ -27,49 +27,51 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.RemoveRoleDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_removeRoles.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = RemoveRoleDomainEvent.class, 
+        domainEvent = ApplicationUser_removeRoles.ActionDomainEvent.class,
         associateWith = "roles")
 @ActionLayout(named="Remove", sequence = "2")
 @RequiredArgsConstructor
 public class ApplicationUser_removeRoles {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_removeRoles> {}
+
     @Inject private MessageService messageService;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
     private final ApplicationUser target;
 
-    
+
     @MemberSupport
     public ApplicationUser act(Collection<ApplicationRole> roles) {
-        
+
         _NullSafe.stream(roles)
         .filter(this::canRemove)
         .forEach(role->applicationRoleRepository.removeRoleFromUser(role, target));
-        
+
         return target;
     }
 
     // same logic in ApplicationRole_removeUsers
     public boolean canRemove(
             final ApplicationRole applicationRole) {
-        
-        if(applicationUserRepository.isAdminUser(target) 
+
+        if(applicationUserRepository.isAdminUser(target)
                 && applicationRoleRepository.isAdminRole(applicationRole)) {
             messageService.warnUser("Cannot remove admin user from the admin role.");
             return false;
         }
         return true;
     }
-     
-    
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_resetPassword.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_resetPassword.java
index ae13650..728ec1b 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_resetPassword.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_resetPassword.java
@@ -27,21 +27,24 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.value.Password;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.ResetPasswordDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_resetPassword.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = ResetPasswordDomainEvent.class, 
+        domainEvent = ApplicationUser_resetPassword.ActionDomainEvent.class,
         associateWith = "hasPassword")
 @ActionLayout(sequence = "20")
 @RequiredArgsConstructor
 public class ApplicationUser_resetPassword {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_resetPassword> {}
+
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -50,7 +53,7 @@ public class ApplicationUser_resetPassword {
             final Password newPassword,
             @ParameterLayout(named="Repeat password")
             final Password newPasswordRepeat) {
-        
+
         applicationUserRepository.updatePassword(target, newPassword.getPassword());
         return target;
     }
@@ -64,11 +67,11 @@ public class ApplicationUser_resetPassword {
     public String validateAct(
             final Password newPassword,
             final Password newPasswordRepeat) {
-        
+
         if(!applicationUserRepository.isPasswordFeatureEnabled(target)) {
             return "Password feature is not available for this User";
         }
-        
+
         if (!Objects.equals(newPassword, newPasswordRepeat)) {
             return "Passwords do not match";
         }
@@ -76,5 +79,4 @@ public class ApplicationUser_resetPassword {
         return null;
     }
 
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java
index 4e9563e..19389c9 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java
@@ -21,21 +21,24 @@ package org.apache.isis.extensions.secman.model.dom.user;
 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.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UnlockDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_unlock.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UnlockDomainEvent.class, 
+        domainEvent = ApplicationUser_unlock.ActionDomainEvent.class,
         associateWith = "status")
 @ActionLayout(
         named="Enable", // symmetry with lock (disable)
         sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationUser_unlock {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_unlock> {}
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -43,9 +46,10 @@ public class ApplicationUser_unlock {
         target.setStatus(ApplicationUserStatus.ENABLED);
         return target;
     }
-    
+
     @MemberSupport
     public String disableAct() {
         return target.getStatus() == ApplicationUserStatus.ENABLED ? "Status is already set to ENABLE": null;
     }
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAccountType.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAccountType.java
index b6ff677..233b104 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAccountType.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAccountType.java
@@ -23,22 +23,25 @@ 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.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.AccountType;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdateAccountTypeDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateAccountType.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateAccountTypeDomainEvent.class, 
+        domainEvent = ApplicationUser_updateAccountType.ActionDomainEvent.class,
         associateWith = "accountType")
-@ActionLayout(sequence = "1")
+@ActionLayout(sequence = "1", position = ActionLayout.Position.RIGHT)
 @RequiredArgsConstructor
 public class ApplicationUser_updateAccountType {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateAccountType> {}
+
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -47,14 +50,14 @@ public class ApplicationUser_updateAccountType {
         target.setAccountType(accountType);
         return target;
     }
-    
+
     @MemberSupport
     public String disableAct() {
         return applicationUserRepository.isAdminUser(target)
                 ? "Cannot change account type for admin user"
                         : null;
     }
-    
+
     @MemberSupport
     public AccountType default0Act() {
         return target.getAccountType();
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java
index c012fc8..a45146f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java
@@ -24,18 +24,21 @@ 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.ParameterLayout;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdateAtPathDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateAtPath.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateAtPathDomainEvent.class, 
+        domainEvent = ApplicationUser_updateAtPath.ActionDomainEvent.class,
         associateWith = "atPath")
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationUser_updateAtPath {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateAtPath> {}
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -52,5 +55,4 @@ public class ApplicationUser_updateAtPath {
         return target.getAtPath();
     }
 
-
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java
index 8790355..ddc6272 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java
@@ -23,18 +23,22 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdateEmailAddressDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateEmailAddress.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateEmailAddressDomainEvent.class, 
+        domainEvent = ApplicationUser_updateEmailAddress.ActionDomainEvent.class,
         associateWith = "emailAddress")
-@ActionLayout(sequence = "1")
+@ActionLayout(sequence = "1", promptStyle = PromptStyle.INLINE_AS_IF_EDIT)
 @RequiredArgsConstructor
 public class ApplicationUser_updateEmailAddress {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateEmailAddress> {}
+
     private final ApplicationUser target;
 
     @MemberSupport
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateFaxNumber.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateFaxNumber.java
index 9add764..a6963f5 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateFaxNumber.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateFaxNumber.java
@@ -24,18 +24,22 @@ 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.ParameterLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdateFaxNumberDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateFaxNumber.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateFaxNumberDomainEvent.class, 
+        domainEvent = ApplicationUser_updateFaxNumber.ActionDomainEvent.class,
         associateWith = "faxNumber")
-@ActionLayout(sequence = "1")
+@ActionLayout(sequence = "1", promptStyle = PromptStyle.INLINE_AS_IF_EDIT)
 @RequiredArgsConstructor
 public class ApplicationUser_updateFaxNumber {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateFaxNumber> {}
+
     private final ApplicationUser holder;
 
     @MemberSupport
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java
index 28c1bcb..ffb51c9 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java
@@ -24,18 +24,21 @@ 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.ParameterLayout;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdateNameDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateName.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateNameDomainEvent.class, 
-        associateWith = "knownAs")
+        domainEvent = ApplicationUser_updateName.ActionDomainEvent.class,
+        associateWith = "familyName")
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationUser_updateName {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateName> {}
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -53,6 +56,7 @@ public class ApplicationUser_updateName {
         target.setFamilyName(familyName);
         target.setGivenName(givenName);
         target.setKnownAs(knownAs);
+
         return target;
     }
 
@@ -86,4 +90,5 @@ public class ApplicationUser_updateName {
         }
         return null;
     }
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePassword.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePassword.java
index 6fe21e5..0ab1835 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePassword.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePassword.java
@@ -29,35 +29,36 @@ import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.value.Password;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.encryption.PasswordEncryptionService;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdatePasswordDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updatePassword.ActionDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @Action(
-        domainEvent = UpdatePasswordDomainEvent.class, 
+        domainEvent = ApplicationUser_updatePassword.ActionDomainEvent.class,
         associateWith = "hasPassword")
 @ActionLayout(sequence = "10")
 @RequiredArgsConstructor
 public class ApplicationUser_updatePassword {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updatePassword> {}
+
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private Optional<PasswordEncryptionService> passwordEncryptionService; // empty if no candidate is available
-    
+
     private final ApplicationUser target;
 
     @MemberSupport
     public ApplicationUser act(
-            @ParameterLayout(named="Existing password")
             final Password existingPassword,
-            @ParameterLayout(named="New password")
             final Password newPassword,
             @ParameterLayout(named="Re-enter password")
             final Password newPasswordRepeat) {
-        
+
         applicationUserRepository.updatePassword(target, newPassword.getPassword());
         return target;
     }
@@ -90,9 +91,9 @@ public class ApplicationUser_updatePassword {
         }
 
         val encrypter = passwordEncryptionService.orElseThrow(_Exceptions::unexpectedCodeReach);
-        
+
         val encryptedPassword = target.getEncryptedPassword();
-        
+
         if(target.getEncryptedPassword() != null) {
             if (!encrypter.matches(existingPassword.getPassword(), encryptedPassword)) {
                 return "Existing password is incorrect";
@@ -105,6 +106,6 @@ public class ApplicationUser_updatePassword {
 
         return null;
     }
-    
+
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java
index c72c105..48e49f1 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java
@@ -24,18 +24,22 @@ 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.ParameterLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdatePhoneNumberDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updatePhoneNumber.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdatePhoneNumberDomainEvent.class, 
+        domainEvent = ApplicationUser_updatePhoneNumber.ActionDomainEvent.class,
         associateWith = "phoneNumber")
-@ActionLayout(sequence = "1")
+@ActionLayout(sequence = "1", promptStyle = PromptStyle.INLINE_AS_IF_EDIT)
 @RequiredArgsConstructor
 public class ApplicationUser_updatePhoneNumber {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updatePhoneNumber> {}
+
     private final ApplicationUser target;
 
     @MemberSupport
@@ -51,9 +55,10 @@ public class ApplicationUser_updatePhoneNumber {
     public String disableAct() {
         return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
-    
+
     @MemberSupport
     public String default0Act() {
         return target.getPhoneNumber();
     }
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java
index 1ca0f12..11ae78f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java
@@ -23,18 +23,21 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.UpdateUsernameDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateUsername.ActionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateUsernameDomainEvent.class, 
+        domainEvent = ApplicationUser_updateUsername.ActionDomainEvent.class,
         associateWith = "username")
-@ActionLayout(sequence = "1")
+@ActionLayout(sequence = "1", position = ActionLayout.Position.RIGHT)
 @RequiredArgsConstructor
 public class ApplicationUser_updateUsername {
-    
+
+    public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateUsername> {}
+
     private final ApplicationUser target;
 
     @MemberSupport
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/menu/ImpersonateMenuAdvisorForSecman.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/menu/ImpersonateMenuAdvisorForSecman.java
index f7c6d22..55f61a3 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/menu/ImpersonateMenuAdvisorForSecman.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/menu/ImpersonateMenuAdvisorForSecman.java
@@ -1,6 +1,8 @@
 package org.apache.isis.extensions.secman.model.menu;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
@@ -41,7 +43,7 @@ public class ImpersonateMenuAdvisorForSecman implements ImpersonateMenuAdvisor {
         return this.applicationUserRepository.allUsers()
                 .stream()
                 .filter(x -> x.getStatus() == ApplicationUserStatus.ENABLED)
-                .map(ApplicationUser::getName)
+                .map(ApplicationUser::getUsername)
                 .collect(Collectors.toList());
     }
 
@@ -56,6 +58,9 @@ public class ImpersonateMenuAdvisorForSecman implements ImpersonateMenuAdvisor {
     @Override
     public List<String> roleNamesFor(
             final String username) {
+        if(username == null) {
+            return null;
+        }
         val applicationUser =
                 applicationUserRepository.findByUsername(username)
                         .orElseThrow(RuntimeException::new);
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.java
index 3b56664..4ea2885 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.java
@@ -121,255 +121,194 @@ import lombok.val;
 public class ApplicationUser implements Comparable<ApplicationUser>,
 org.apache.isis.extensions.secman.api.user.ApplicationUser {
 
-    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private ApplicationPermissionRepository applicationPermissionRepository;
     @Inject private UserService userService;
     /**
      * Optional service, if configured then is used to evaluate permissions within
      * {@link org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValueSet#evaluate(ApplicationFeatureId, ApplicationPermissionMode)}
-     * else will fallback to a {@link org.apache.isis.extensions.secman.api.permission.PermissionsEvaluationService#DEFAULT default}
+     * else will fallback to a default.
      * implementation.
      */
     @Inject private PermissionsEvaluationService permissionsEvaluationService;
     @Inject private SecmanConfiguration configBean;
 
-    // -- name (derived property)
-
-    public static class NameDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Override
-    @javax.jdo.annotations.NotPersistent
-    @Property(
-            domainEvent = NameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
-    @PropertyLayout(
-            hidden=Where.OBJECT_FORMS,
-            fieldSetId="Id", 
-            sequence = "1")
-    public String getName() {
-        final StringBuilder buf = new StringBuilder();
-        if(getFamilyName() != null) {
-            if(getKnownAs() != null) {
-                buf.append(getKnownAs());
-            } else {
-                buf.append(getGivenName());
-            }
-            buf.append(' ')
-            .append(getFamilyName())
-            .append(" (").append(getUsername()).append(')');
-        } else {
-            buf.append(getUsername());
-        }
-        return buf.toString();
-    }
 
 
     // -- username (property)
 
-    public static class UsernameDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="false", length = MAX_LENGTH_USERNAME)
     @Property(
             domainEvent = UsernameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_USERNAME
+    )
     @PropertyLayout(
             hidden=Where.PARENTED_TABLES,
-            fieldSetId="Id", 
+            fieldSetId="Id",
             sequence = "1")
+    @javax.jdo.annotations.Column(allowsNull="false", length = MAX_LENGTH_USERNAME)
     @Getter @Setter
     private String username;
 
 
     // -- familyName (property)
 
-    public static class FamilyNameDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_FAMILY_NAME)
     @Property(
             domainEvent = FamilyNameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_FAMILY_NAME
+    )
     @PropertyLayout(
             hidden=Where.ALL_TABLES,
             fieldSetId="Name",
             sequence = "2.1")
+    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_FAMILY_NAME)
     @Getter @Setter
     private String familyName;
 
 
     // -- givenName (property)
 
-    public static class GivenNameDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_GIVEN_NAME)
     @Property(
             domainEvent = GivenNameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_KNOWN_AS
+    )
     @PropertyLayout(
             hidden=Where.ALL_TABLES,
-            fieldSetId="Name", 
+            fieldSetId="Name",
             sequence = "2.2")
+    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_GIVEN_NAME)
     @Getter @Setter
     private String givenName;
 
 
     // -- knownAs (property)
 
-    public static class KnownAsDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_KNOWN_AS)
     @Property(
             domainEvent = KnownAsDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_KNOWN_AS
+    )
     @PropertyLayout(
             hidden=Where.ALL_TABLES,
             fieldSetId="Name",
             sequence = "2.3")
+    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_KNOWN_AS)
     @Getter @Setter
     private String knownAs;
 
 
     // -- emailAddress (property)
 
-    public static class EmailAddressDomainEvent extends PropertyDomainEvent<String> {}
-
-    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_EMAIL_ADDRESS)
     @Property(
             domainEvent = EmailAddressDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_EMAIL_ADDRESS
+    )
     @PropertyLayout(fieldSetId="Contact Details", sequence = "3.1")
+    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_EMAIL_ADDRESS)
     @Getter @Setter
     private String emailAddress;
 
 
     // -- phoneNumber (property)
 
-    public static class PhoneNumberDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_PHONE_NUMBER)
     @Property(
             domainEvent = PhoneNumberDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_PHONE_NUMBER
+    )
     @PropertyLayout(fieldSetId="Contact Details", sequence = "3.2")
+    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_PHONE_NUMBER)
     @Getter @Setter
     private String phoneNumber;
 
 
     // -- faxNumber (property)
 
-    public static class FaxNumberDomainEvent extends PropertyDomainEvent<String> {}
-
-    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_PHONE_NUMBER)
     @Property(
             domainEvent = FaxNumberDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_PHONE_NUMBER
+    )
     @PropertyLayout(
             hidden=Where.PARENTED_TABLES,
-            fieldSetId="Contact Details", 
+            fieldSetId="Contact Details",
             sequence = "3.3")
+    @javax.jdo.annotations.Column(allowsNull="true", length = MAX_LENGTH_PHONE_NUMBER)
     @Getter @Setter
     private String faxNumber;
 
 
     // -- atPath (property)
 
-    public static class AtPathDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @javax.jdo.annotations.Column(name = "atPath", allowsNull="true")
     @Property(
             domainEvent = AtPathDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_AT_PATH
+    )
     @PropertyLayout(fieldSetId="atPath", sequence = "3.4")
+    @javax.jdo.annotations.Column(name = "atPath", allowsNull="true", length = MAX_LENGTH_AT_PATH)
     @Getter @Setter
     private String atPath;
 
     // -- accountType (property)
 
-    public static class AccountTypeDomainEvent extends PropertyDomainEvent<AccountType> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="false")
     @Property(
             domainEvent = AccountTypeDomainEvent.class,
             editing = Editing.DISABLED
-            )
+    )
     @PropertyLayout(fieldSetId="Status", sequence = "3")
+    @javax.jdo.annotations.Column(allowsNull="false")
     @Getter @Setter
     private AccountType accountType;
 
 
-    // -- status (property), visible (action), usable (action)
+    // -- status (property)
 
-    public static class StatusDomainEvent extends PropertyDomainEvent<ApplicationUserStatus> {}
-
-
-    @javax.jdo.annotations.Column(allowsNull="false")
     @Property(
             domainEvent = StatusDomainEvent.class,
             editing = Editing.DISABLED
-            )
+    )
     @PropertyLayout(fieldSetId="Status", sequence = "4")
+    @javax.jdo.annotations.Column(allowsNull="false")
     @Getter @Setter
     private ApplicationUserStatus status;
 
 
     // -- encryptedPassword (hidden property)
 
-
-    @javax.jdo.annotations.Column(allowsNull="true")
     @PropertyLayout(hidden=Where.EVERYWHERE)
+    @javax.jdo.annotations.Column(allowsNull="true")
     @Getter @Setter
     private String encryptedPassword;
 
-    public boolean hideEncryptedPassword() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(this);
-    }
 
 
     // -- hasPassword (derived property)
 
-    public static class HasPasswordDomainEvent extends PropertyDomainEvent<Boolean> {}
-
     @Property(
             domainEvent = HasPasswordDomainEvent.class,
             editing = Editing.DISABLED
-            )
+    )
     @PropertyLayout(fieldSetId="Status", sequence = "4")
     @Override
     public boolean isHasPassword() {
-        return _Strings.isNotEmpty(getEncryptedPassword());
+        return org.apache.isis.extensions.secman.api.user.ApplicationUser.super.isHasPassword();
     }
 
-    public boolean hideHasPassword() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(this);
-    }
 
     // -- roles (collection)
-    public static class RolesDomainEvent extends CollectionDomainEvent<ApplicationRole> {}
 
-    @javax.jdo.annotations.Persistent(table="ApplicationUserRoles")
-    @javax.jdo.annotations.Join(column="userId")
-    @javax.jdo.annotations.Element(column="roleId")
     @Collection(
             domainEvent = RolesDomainEvent.class
-            )
+    )
     @CollectionLayout(
             defaultView="table",
             sequence = "20")
+    @javax.jdo.annotations.Persistent(table="ApplicationUserRoles")
+    @javax.jdo.annotations.Join(column="userId")
+    @javax.jdo.annotations.Element(column="roleId")
     @Getter @Setter
     private Set<ApplicationRole> roles = new TreeSet<>();
 
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.layout.fallback.xml b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.layout.fallback.xml
index 4b43b4c..0d84208 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.layout.fallback.xml
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUser.layout.fallback.xml
@@ -26,46 +26,81 @@ under the License.
         </bs3:col>
     </bs3:row>
     <bs3:row>
-        <bs3:col span="4">
-            <cpt:fieldSet name="Id" id="id" unreferencedProperties="true">
-                <cpt:property id="name"/>
-                <cpt:property id="username"/>
-                <cpt:property id="encryptedPassword"/>
-            </cpt:fieldSet>
+        <bs3:col span="3">
+			<bs3:row>
+				<bs3:col span="12">
+					<bs3:tabGroup>
+						<bs3:tab name="Identity">
+							<bs3:row>
+								<bs3:col span="12">
+									<cpt:fieldSet name="Identity" id="identity"/>
+								</bs3:col>
+							</bs3:row>
+						</bs3:tab>
+						<bs3:tab name="Other">
+							<bs3:row>
+								<bs3:col span="12">
+									<cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+								</bs3:col>
+							</bs3:row>
+						</bs3:tab>
+						<bs3:tab name="Metadata">
+							<bs3:row>
+								<bs3:col span="12">
+									<cpt:fieldSet name="Metadata" id="metadata">
+										<cpt:property id="objectType"/>
+										<cpt:property id="objectIdentifier"/>
+										<cpt:property id="datanucleusIdLong" hidden="EVERYWHERE"/>
+										<cpt:property id="datanucleusVersionLong"/>
+										<cpt:property id="datanucleusVersionTimestamp"/>
+									</cpt:fieldSet>
+								</bs3:col>
+							</bs3:row>
+						</bs3:tab>
+					</bs3:tabGroup>
+				</bs3:col>
+			</bs3:row>
             <cpt:fieldSet name="Status" id="status">
                 <cpt:property id="accountType"/>
-                <cpt:property id="hasPassword"/>
                 <cpt:property id="status"/>
                 <cpt:property id="atPath"/>
             </cpt:fieldSet>
-            <cpt:fieldSet name="Metadata" id="metadata">
-                <cpt:property id="datanucleusIdLong"/>
-                <cpt:property id="datanucleusVersionLong"/>
-                <cpt:property id="datanucleusVersionTimestamp"/>
-            </cpt:fieldSet>
         </bs3:col>
-        <bs3:col span="8">
+		<bs3:col span="3">
+			<bs3:tabGroup>
+				<bs3:tab name="Name">
+					<bs3:row>
+						<bs3:col span="12">
+							<cpt:fieldSet name="Name" id="name">
+								<cpt:property id="familyName">
+									<cpt:action id="updateName"/>
+								</cpt:property>
+								<cpt:property id="givenName"/>
+								<cpt:property id="knownAs"/>
+							</cpt:fieldSet>
+						</bs3:col>
+					</bs3:row>
+				</bs3:tab>
+				<bs3:tab name="Contact Details">
+					<bs3:row>
+						<bs3:col span="12">
+							<cpt:fieldSet name="Contact Details" id="contactDetails">
+								<cpt:property id="emailAddress"/>
+								<cpt:property id="phoneNumber"/>
+								<cpt:property id="faxNumber"/>
+							</cpt:fieldSet>
+						</bs3:col>
+					</bs3:row>
+				</bs3:tab>
+			</bs3:tabGroup>
+			<cpt:fieldSet name="Password" id="password">
+                <cpt:property id="hasPassword"/>
+			</cpt:fieldSet>
+		</bs3:col>
+        <bs3:col span="6">
         	<bs3:row>
         		<bs3:col span="12">
         			<bs3:tabGroup>
-        				<bs3:tab name="Name and Contact Details">
-        					<bs3:row>
-        						<bs3:col span="6">
-						            <cpt:fieldSet name="Contact Details" id="contactDetails">
-						                <cpt:property id="emailAddress"/>
-						                <cpt:property id="phoneNumber"/>
-						                <cpt:property id="faxNumber"/>
-						            </cpt:fieldSet>
-        						</bs3:col>
-        						<bs3:col span="6">
-						            <cpt:fieldSet name="Name" id="name">
-						                <cpt:property id="familyName"/>
-						                <cpt:property id="givenName"/>
-						                <cpt:property id="knownAs"/>
-						            </cpt:fieldSet>						            
-        						</bs3:col>
-        					</bs3:row>
-        				</bs3:tab>
 		        		<bs3:tab name="Roles">
 		        			<bs3:row>
 		        				<bs3:col span="12">
@@ -80,14 +115,14 @@ under the License.
 		        				</bs3:col>
 		        			</bs3:row>
 		        		</bs3:tab>
-		        		<bs3:tab name="Other">
-		        			<bs3:row>
-		        				<bs3:col span="12" unreferencedCollections="true" />
-		        			</bs3:row>
-		        		</bs3:tab>
         			</bs3:tabGroup>
         		</bs3:col>
         	</bs3:row>
         </bs3:col>
     </bs3:row>
-</bs3:grid>
\ No newline at end of file
+	<bs3:row>
+		<bs3:col span="12">
+			<bs3:tabGroup unreferencedCollections="true"/>
+		</bs3:col>
+	</bs3:row>
+</bs3:grid>
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java
index 09cd8f1..55a5b44 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java
@@ -24,42 +24,42 @@ import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewDelegateUserDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser.ActionDomainEvent;
 import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
 import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = NewDelegateUserDomainEvent.class, 
+        domainEvent = ActionDomainEvent.class,
         associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newDelegateUser
 extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser<ApplicationRole>{
-    
+
     private final ApplicationUserManager target;
-    
+
     @MemberSupport
     public ApplicationUserManager act(
-            
+
           @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
           @ParameterLayout(named = "Name")
           final String username,
-            
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Initial role")
           final ApplicationRole initialRole,
-            
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Enabled?")
           final Boolean enabled
-            
+
             ) {
-        
+
         super.doAct(username, initialRole, enabled);
-        return target; 
+        return target;
     }
-    
+
     @MemberSupport
     public boolean hideAct() {
         return super.doHide();
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java
index 3aa1286..97dc218 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java
@@ -25,51 +25,51 @@ import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.value.Password;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewLocalUserDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser.ActionDomainEvent;
 import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
 import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = NewLocalUserDomainEvent.class, 
+        domainEvent = ActionDomainEvent.class,
         associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newLocalUser
 extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser<ApplicationRole> {
-    
+
     private final ApplicationUserManager target;
-    
+
     @MemberSupport
     public ApplicationUserManager act(
           @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
           @ParameterLayout(named = "Name")
           final String username,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Password")
           final Password password,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Repeat password")
           final Password passwordRepeat,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Initial role")
           final ApplicationRole initialRole,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Enabled?")
           final Boolean enabled,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Email Address")
           final String emailAddress) {
-        
+
         super.doAct(username, password, passwordRepeat, initialRole, enabled, emailAddress);
-        return target; 
+        return target;
     }
-    
+
     @MemberSupport
     public String validateAct(
             final String username,
@@ -78,14 +78,14 @@ extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_
             final ApplicationRole initialRole,
             final Boolean enabled,
             final String emailAddress) {
-        
+
         return super.doValidate(username, newPassword, newPasswordRepeat, initialRole, enabled, emailAddress);
     }
-    
+
     @MemberSupport
     public ApplicationRole default3Act() {
         return super.doDefault3();
     }
-  
+
 
 }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java
index 9b60dc3..acd476a 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java
@@ -61,15 +61,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     @Inject private SecmanConfiguration configBean;
     @Inject private Optional<PasswordEncryptionService> passwordEncryptionService; // empty if no candidate is available
 	@Inject protected IsisConfiguration isisConfiguration;
-    @Inject private EventBusService eventBusService;  
- 
+    @Inject private EventBusService eventBusService;
+
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
-    
+
     @Override
     public ApplicationUser newApplicationUser() {
         return factoryService.detachedEntity(new ApplicationUser());
     }
-    
+
     // -- findOrCreateUserByUsername (programmatic)
 
     /**
@@ -85,14 +85,14 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
             final String username) {
         // slightly unusual to cache a function that modifies state, but safe because this is idempotent
         return queryResultsCacheProvider.get().execute(()->
-            findByUsername(username).orElseGet(()->newDelegateUser(username, null)), 
+            findByUsername(username).orElseGet(()->newDelegateUser(username, null)),
             ApplicationUserRepository.class, "findOrCreateUserByUsername", username);
     }
 
     // -- findByUsername
 
     public Optional<ApplicationUser> findByUsernameCached(final String username) {
-        return queryResultsCacheProvider.get().execute(this::findByUsername, 
+        return queryResultsCacheProvider.get().execute(this::findByUsername,
                 ApplicationUserRepository.class, "findByUsernameCached", username);
     }
 
@@ -105,7 +105,7 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     // -- findByEmailAddress (programmatic)
 
     public Optional<ApplicationUser> findByEmailAddressCached(final String emailAddress) {
-        return queryResultsCacheProvider.get().execute(this::findByEmailAddress, 
+        return queryResultsCacheProvider.get().execute(this::findByEmailAddress,
                 ApplicationUserRepository.class, "findByEmailAddressCached", emailAddress);
     }
 
@@ -134,20 +134,20 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
-    
+
     @Override
     public Collection<ApplicationUser> findByRole(
             org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
         return _NullSafe.stream(role.getUsers())
                 .collect(_Sets.toUnmodifiableSorted());
     }
-    
+
     @Override
     public Collection<ApplicationUser> findByTenancy(
             @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
-        return findByAtPath(genericTenancy.getPath()) 
+        return findByAtPath(genericTenancy.getPath())
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
@@ -168,9 +168,9 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         }
         return Collections.emptySortedSet();
     }
-    
+
     // -- UPDATE USER STATE
-    
+
     @Override
     public void enable(org.apache.isis.extensions.secman.api.user.ApplicationUser user) {
         if(user.getStatus() != ApplicationUserStatus.ENABLED) {
@@ -189,15 +189,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
 
     @Override
     public boolean isAdminUser(org.apache.isis.extensions.secman.api.user.ApplicationUser user) {
-        return configBean.getAdminUserName().equals(user.getName());
+        return configBean.getAdminUserName().equals(user.getUsername());
     }
 
     @Override
     public ApplicationUser newUser(
-            @NonNull String username, 
+            @NonNull String username,
             @Nullable AccountType accountType,
             Consumer<ApplicationUser> beforePersist) {
-        
+
         val user = newApplicationUser();
         user.setUsername(username);
         user.setAccountType(accountType);
@@ -205,18 +205,18 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         if(user.getAccountType().equals(AccountType.LOCAL)) {
         	// keep null when is set for status in accept() call above
         } else {
-			user.setStatus(configBean.isAutoEnableIfDelegatedAndAuthenticated() 
-			        ?  ApplicationUserStatus.ENABLED 
+			user.setStatus(configBean.isAutoEnableIfDelegatedAndAuthenticated()
+			        ?  ApplicationUserStatus.ENABLED
 	                :  ApplicationUserStatus.DISABLED);
         }
         repository.persistAndFlush(user);
         eventBusService.post(UserCreatedEvent.of(user));
         return user;
     }
-    
+
     @Override
     public boolean updatePassword(
-            final org.apache.isis.extensions.secman.api.user.ApplicationUser user, 
+            final org.apache.isis.extensions.secman.api.user.ApplicationUser user,
             final String password) {
         // in case called programmatically
         if(!isPasswordFeatureEnabled(user)) {
@@ -227,15 +227,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         repository.persistAndFlush(user);
         return true;
     }
-    
+
     @Override
     public boolean isPasswordFeatureEnabled(org.apache.isis.extensions.secman.api.user.ApplicationUser user) {
-        return user.isLocalAccount() 
+        return user.isLocalAccount()
                 /*sonar-ignore-on*/
                 && passwordEncryptionService!=null // if for any reason injection fails
                 /*sonar-ignore-off*/
                 && passwordEncryptionService.isPresent();
     }
 
-    
+
 }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUser.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUser.java
index ca82ce2..b14455d 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUser.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUser.java
@@ -39,6 +39,7 @@ import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
+import javax.persistence.Version;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
 import org.apache.isis.applib.annotation.Collection;
@@ -121,13 +122,12 @@ import lombok.val;
 public class ApplicationUser implements Comparable<ApplicationUser>,
 org.apache.isis.extensions.secman.api.user.ApplicationUser {
 
-    @Inject private transient ApplicationUserRepository applicationUserRepository;
     @Inject private transient ApplicationPermissionRepository applicationPermissionRepository;
     @Inject private transient UserService userService;
     /**
      * Optional service, if configured then is used to evaluate permissions within
      * {@link org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValueSet#evaluate(ApplicationFeatureId, ApplicationPermissionMode)}
-     * else will fallback to a {@link org.apache.isis.extensions.secman.api.permission.PermissionsEvaluationService#DEFAULT default}
+     * else will fallback to a default.
      * implementation.
      */
     @Inject private transient PermissionsEvaluationService permissionsEvaluationService;
@@ -137,247 +137,189 @@ org.apache.isis.extensions.secman.api.user.ApplicationUser {
     @GeneratedValue
     private Long id;
 
-    // -- name (derived property)
-
-    public static class NameDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Override
-    @javax.persistence.Transient
-    @Property(
-            domainEvent = NameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
-    @PropertyLayout(
-            hidden=Where.OBJECT_FORMS,
-            fieldSetId="Id", 
-            sequence = "1")
-    public String getName() {
-        final StringBuilder buf = new StringBuilder();
-        if(getFamilyName() != null) {
-            if(getKnownAs() != null) {
-                buf.append(getKnownAs());
-            } else {
-                buf.append(getGivenName());
-            }
-            buf.append(' ')
-            .append(getFamilyName())
-            .append(" (").append(getUsername()).append(')');
-        } else {
-            buf.append(getUsername());
-        }
-        return buf.toString();
-    }
+    @Version
+    private Long version;
 
 
     // -- username (property)
 
-    public static class UsernameDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Column(nullable=false, length=MAX_LENGTH_USERNAME)
     @Property(
             domainEvent = UsernameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_USERNAME
+    )
     @PropertyLayout(
             hidden=Where.PARENTED_TABLES,
-            fieldSetId="Id", 
+            fieldSetId="Id",
             sequence = "1")
+    @Column(nullable=false, length=MAX_LENGTH_USERNAME)
     @Getter @Setter
     private String username;
 
 
     // -- familyName (property)
 
-    public static class FamilyNameDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Column(nullable=true, length=MAX_LENGTH_FAMILY_NAME)
     @Property(
             domainEvent = FamilyNameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_FAMILY_NAME
+    )
     @PropertyLayout(
             hidden=Where.ALL_TABLES,
             fieldSetId="Name",
             sequence = "2.1")
+    @Column(nullable=true, length=MAX_LENGTH_FAMILY_NAME)
     @Getter @Setter
     private String familyName;
 
 
     // -- givenName (property)
 
-    public static class GivenNameDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Column(nullable=true, length=MAX_LENGTH_GIVEN_NAME)
     @Property(
             domainEvent = GivenNameDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_KNOWN_AS
+    )
     @PropertyLayout(
-            hidden=Where.ALL_TABLES, 
-            fieldSetId="Name", 
+            hidden=Where.ALL_TABLES,
+            fieldSetId="Name",
             sequence = "2.2")
+    @Column(nullable=true, length=MAX_LENGTH_GIVEN_NAME)
     @Getter @Setter
     private String givenName;
 
 
     // -- knownAs (property)
 
-    public static class KnownAsDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @Column(nullable=true, length=MAX_LENGTH_KNOWN_AS)
     @Property(
             domainEvent = KnownAsDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_KNOWN_AS
+    )
     @PropertyLayout(
             hidden=Where.ALL_TABLES,
             fieldSetId="Name",
             sequence = "2.3")
+    @Column(nullable=true, length=MAX_LENGTH_KNOWN_AS)
     @Getter @Setter
     private String knownAs;
 
 
     // -- emailAddress (property)
 
-    public static class EmailAddressDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Column(nullable=true, length=MAX_LENGTH_EMAIL_ADDRESS)
     @Property(
             domainEvent = EmailAddressDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_EMAIL_ADDRESS
+    )
     @PropertyLayout(fieldSetId="Contact Details", sequence = "3.1")
+    @Column(nullable=true, length=MAX_LENGTH_EMAIL_ADDRESS)
     @Getter @Setter
     private String emailAddress;
 
 
     // -- phoneNumber (property)
 
-    public static class PhoneNumberDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @Column(nullable=true, length=MAX_LENGTH_PHONE_NUMBER)
     @Property(
             domainEvent = PhoneNumberDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_PHONE_NUMBER
+    )
     @PropertyLayout(fieldSetId="Contact Details", sequence = "3.2")
+    @Column(nullable=true, length=MAX_LENGTH_PHONE_NUMBER)
     @Getter @Setter
     private String phoneNumber;
 
 
     // -- faxNumber (property)
 
-    public static class FaxNumberDomainEvent extends PropertyDomainEvent<String> {}
-
-    @Column(nullable=true, length=MAX_LENGTH_PHONE_NUMBER)
     @Property(
             domainEvent = FaxNumberDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_PHONE_NUMBER
+    )
     @PropertyLayout(
             hidden=Where.PARENTED_TABLES,
-            fieldSetId="Contact Details", 
+            fieldSetId="Contact Details",
             sequence = "3.3")
+    @Column(nullable=true, length=MAX_LENGTH_PHONE_NUMBER)
     @Getter @Setter
     private String faxNumber;
 
 
     // -- atPath (property)
 
-    public static class AtPathDomainEvent extends PropertyDomainEvent<String> {}
-
-
-    @Column(name="atPath", nullable=true)
     @Property(
             domainEvent = AtPathDomainEvent.class,
-            editing = Editing.DISABLED
-            )
+            editing = Editing.DISABLED,
+            maxLength = MAX_LENGTH_AT_PATH
+    )
     @PropertyLayout(fieldSetId="atPath", sequence = "3.4")
+    @Column(name="atPath", nullable=true, length = MAX_LENGTH_AT_PATH)
     @Getter @Setter
     private String atPath;
 
     // -- accountType (property)
 
-    public static class AccountTypeDomainEvent extends PropertyDomainEvent<AccountType> {}
-
-
-    @Column(nullable=false)
-    @Enumerated(EnumType.STRING)
     @Property(
             domainEvent = AccountTypeDomainEvent.class,
             editing = Editing.DISABLED
-            )
+    )
     @PropertyLayout(fieldSetId="Status", sequence = "3")
+    @Column(nullable=false)
+    @Enumerated(EnumType.STRING)
     @Getter @Setter
     private AccountType accountType;
 
 
-    // -- status (property), visible (action), usable (action)
+    // -- status (property)
 
-    public static class StatusDomainEvent extends PropertyDomainEvent<ApplicationUserStatus> {}
-
-
-    @Column(nullable=false)
-    @Enumerated(EnumType.STRING)
     @Property(
             domainEvent = StatusDomainEvent.class,
             editing = Editing.DISABLED
-            )
+    )
     @PropertyLayout(fieldSetId="Status", sequence = "4")
+    @Column(nullable=false)
+    @Enumerated(EnumType.STRING)
     @Getter @Setter
     private ApplicationUserStatus status;
 
 
     // -- encryptedPassword (hidden property)
 
-
-    @Column(nullable=true)
     @PropertyLayout(hidden=Where.EVERYWHERE)
+    @Column(nullable=true)
     @Getter @Setter
     private String encryptedPassword;
 
-    public boolean hideEncryptedPassword() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(this);
-    }
 
 
     // -- hasPassword (derived property)
 
-    public static class HasPasswordDomainEvent extends PropertyDomainEvent<Boolean> {}
-
     @Property(
             domainEvent = HasPasswordDomainEvent.class,
             editing = Editing.DISABLED
-            )
+    )
     @PropertyLayout(fieldSetId="Status", sequence = "4")
     @Override
     public boolean isHasPassword() {
-        return _Strings.isNotEmpty(getEncryptedPassword());
+        return org.apache.isis.extensions.secman.api.user.ApplicationUser.super.isHasPassword();
     }
 
-    public boolean hideHasPassword() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(this);
-    }
 
     // -- roles (collection)
-    public static class RolesDomainEvent extends CollectionDomainEvent<ApplicationRole> {}
 
-//    @javax.jdo.annotations.Persistent(table="ApplicationUserRoles")
-//    @javax.jdo.annotations.Join(column="userId")
-//    @javax.jdo.annotations.Element(column="roleId")
-    @ManyToMany(mappedBy = "users", cascade = CascadeType.ALL)
-    @JoinTable(
-            name = "ApplicationUserRoles",
-            joinColumns = {@JoinColumn(name = "userId")},
-            inverseJoinColumns = {@JoinColumn(name = "roleId")})
     @Collection(
             domainEvent = RolesDomainEvent.class
-            )
+    )
     @CollectionLayout(
             defaultView="table",
             sequence = "20")
+    @ManyToMany(mappedBy = "users", cascade = CascadeType.ALL)
+    @JoinTable(
+            name = "ApplicationUserRoles",
+            joinColumns = {@JoinColumn(name = "userId")},
+            inverseJoinColumns = {@JoinColumn(name = "roleId")})
     @Getter @Setter
     private Set<ApplicationRole> roles = new TreeSet<>();
 
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java
index c5039d7..9cc2d74 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java
@@ -24,42 +24,42 @@ import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewDelegateUserDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser.ActionDomainEvent;
 import org.apache.isis.extensions.secman.jpa.dom.role.ApplicationRole;
 import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = NewDelegateUserDomainEvent.class, 
+        domainEvent = ActionDomainEvent.class,
         associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newDelegateUser
 extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser<ApplicationRole>{
-    
+
     private final ApplicationUserManager target;
-    
+
     @MemberSupport
     public ApplicationUserManager act(
-            
+
           @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
           @ParameterLayout(named = "Name")
           final String username,
-            
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Initial role")
           final ApplicationRole initialRole,
-            
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Enabled?")
           final Boolean enabled
-            
+
             ) {
-        
+
         super.doAct(username, initialRole, enabled);
         return target;
     }
-    
+
     @MemberSupport
     public boolean hideAct() {
         return super.doHide();
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java
index 53b8bb0..ab9365a 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java
@@ -25,50 +25,50 @@ import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.value.Password;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewLocalUserDomainEvent;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser.ActionDomainEvent;
 import org.apache.isis.extensions.secman.jpa.dom.role.ApplicationRole;
 import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = NewLocalUserDomainEvent.class, 
+        domainEvent = ActionDomainEvent.class,
         associateWith = "allUsers")
 @RequiredArgsConstructor
-public class ApplicationUserManager_newLocalUser 
+public class ApplicationUserManager_newLocalUser
 extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser<ApplicationRole> {
-    
+
     private final ApplicationUserManager target;
-    
+
     @MemberSupport
     public ApplicationUserManager act(
           @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
           @ParameterLayout(named = "Name")
           final String username,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Password")
           final Password password,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Repeat password")
           final Password passwordRepeat,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Initial role")
           final ApplicationRole initialRole,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Enabled?")
           final Boolean enabled,
-          
+
           @Parameter(optionality = Optionality.OPTIONAL)
           @ParameterLayout(named = "Email Address")
           final String emailAddress) {
         super.doAct(username, password, passwordRepeat, initialRole, enabled, emailAddress);
         return target;
     }
-    
+
     @MemberSupport
     public String validateAct(
             final String username,
@@ -77,10 +77,10 @@ extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_
             final ApplicationRole initialRole,
             final Boolean enabled,
             final String emailAddress) {
-        
+
         return super.doValidate(username, newPassword, newPasswordRepeat, initialRole, enabled, emailAddress);
     }
-    
+
     @MemberSupport
     public ApplicationRole default3Act() {
         return super.doDefault3();
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserRepository.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserRepository.java
index be9f2ba..f39cff0 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserRepository.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserRepository.java
@@ -63,15 +63,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     @Inject private SecmanConfiguration configBean;
     @Inject private Optional<PasswordEncryptionService> passwordEncryptionService; // empty if no candidate is available
 	@Inject protected IsisConfiguration isisConfiguration;
-    @Inject private EventBusService eventBusService;  
- 
+    @Inject private EventBusService eventBusService;
+
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
-    
+
     @Override
     public ApplicationUser newApplicationUser() {
         return factoryService.detachedEntity(new ApplicationUser());
     }
-    
+
     // -- findOrCreateUserByUsername (programmatic)
 
     /**
@@ -87,14 +87,14 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
             final String username) {
         // slightly unusual to cache a function that modifies state, but safe because this is idempotent
         return queryResultsCacheProvider.get().execute(()->
-            findByUsername(username).orElseGet(()->newDelegateUser(username, null)), 
+            findByUsername(username).orElseGet(()->newDelegateUser(username, null)),
             ApplicationUserRepository.class, "findOrCreateUserByUsername", username);
     }
 
     // -- findByUsername
 
     public Optional<ApplicationUser> findByUsernameCached(final String username) {
-        return queryResultsCacheProvider.get().execute(this::findByUsername, 
+        return queryResultsCacheProvider.get().execute(this::findByUsername,
                 ApplicationUserRepository.class, "findByUsernameCached", username);
     }
 
@@ -107,7 +107,7 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     // -- findByEmailAddress (programmatic)
 
     public Optional<ApplicationUser> findByEmailAddressCached(final String emailAddress) {
-        return queryResultsCacheProvider.get().execute(this::findByEmailAddress, 
+        return queryResultsCacheProvider.get().execute(this::findByEmailAddress,
                 ApplicationUserRepository.class, "findByEmailAddressCached", emailAddress);
     }
 
@@ -137,20 +137,20 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
-    
+
     @Override
     public Collection<ApplicationUser> findByRole(
             org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
         return _NullSafe.stream(role.getUsers())
                 .collect(_Sets.toUnmodifiableSorted());
     }
-    
+
     @Override
     public Collection<ApplicationUser> findByTenancy(
             @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
-        return findByAtPath(genericTenancy.getPath()) 
+        return findByAtPath(genericTenancy.getPath())
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
@@ -171,9 +171,9 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         }
         return Collections.emptySortedSet();
     }
-    
+
     // -- UPDATE USER STATE
-    
+
     @Override
     public void enable(org.apache.isis.extensions.secman.api.user.ApplicationUser user) {
         if(user.getStatus() != ApplicationUserStatus.ENABLED) {
@@ -192,15 +192,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
 
     @Override
     public boolean isAdminUser(org.apache.isis.extensions.secman.api.user.ApplicationUser user) {
-        return configBean.getAdminUserName().equals(user.getName());
+        return configBean.getAdminUserName().equals(user.getUsername());
     }
 
     @Override
     public ApplicationUser newUser(
-            @NonNull String username, 
+            @NonNull String username,
             @Nullable AccountType accountType,
             Consumer<ApplicationUser> beforePersist) {
-        
+
         val user = newApplicationUser();
         user.setUsername(username);
         user.setAccountType(accountType);
@@ -208,18 +208,18 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         if(user.getAccountType().equals(AccountType.LOCAL)) {
         	// keep null when is set for status in accept() call above
         } else {
-			user.setStatus(configBean.isAutoEnableIfDelegatedAndAuthenticated() 
-			        ?  ApplicationUserStatus.ENABLED 
+			user.setStatus(configBean.isAutoEnableIfDelegatedAndAuthenticated()
+			        ?  ApplicationUserStatus.ENABLED
 	                :  ApplicationUserStatus.DISABLED);
         }
         repository.persistAndFlush(user);
         eventBusService.post(UserCreatedEvent.of(user));
         return user;
     }
-    
+
     @Override
     public boolean updatePassword(
-            final org.apache.isis.extensions.secman.api.user.ApplicationUser user, 
+            final org.apache.isis.extensions.secman.api.user.ApplicationUser user,
             final String password) {
         // in case called programmatically
         if(!isPasswordFeatureEnabled(user)) {
@@ -230,15 +230,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         repository.persistAndFlush(user);
         return true;
     }
-    
+
     @Override
     public boolean isPasswordFeatureEnabled(org.apache.isis.extensions.secman.api.user.ApplicationUser user) {
-        return user.isLocalAccount() 
+        return user.isLocalAccount()
                 /*sonar-ignore-on*/
                 && passwordEncryptionService!=null // if for any reason injection fails
                 /*sonar-ignore-off*/
                 && passwordEncryptionService.isPresent();
     }
 
-    
+
 }
diff --git a/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PrincipalForApplicationUser.java b/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PrincipalForApplicationUser.java
index 2cd62a9..985f153 100644
--- a/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PrincipalForApplicationUser.java
+++ b/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PrincipalForApplicationUser.java
@@ -55,7 +55,7 @@ import lombok.val;
  * </p>
  *
  * TODO: this should probably implement java.security.Principal so that it doesn't get wrapped in a
- * ShiroHttpServletRequest.ObjectPrincipal. 
+ * ShiroHttpServletRequest.ObjectPrincipal.
  * Such a change would need some testing to avoid regressions, though.
  */
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@@ -67,7 +67,7 @@ class PrincipalForApplicationUser implements AuthorizationInfo {
         if(applicationUser == null) {
             return null;
         }
-        val username = applicationUser.getName();
+        val username = applicationUser.getUsername();
         val encryptedPassword = applicationUser.getEncryptedPassword();
         val accountType = applicationUser.getAccountType();
         val roles = applicationUser.getRoles()
@@ -75,8 +75,8 @@ class PrincipalForApplicationUser implements AuthorizationInfo {
                 .map(ApplicationRole::getName)
                 .collect(Collectors.toCollection(TreeSet::new));
         val permissionSet = applicationUser.getPermissionSet();
-        
-        return new PrincipalForApplicationUser(username, encryptedPassword, accountType, 
+
+        return new PrincipalForApplicationUser(username, encryptedPassword, accountType,
                 applicationUser.getStatus(), roles, permissionSet);
     }
 
@@ -86,7 +86,7 @@ class PrincipalForApplicationUser implements AuthorizationInfo {
     @Getter(value = AccessLevel.PACKAGE) private final ApplicationUserStatus status;
     @Getter(value = AccessLevel.PUBLIC)  private final Set<String> roles;
     @Getter(value = AccessLevel.PACKAGE) private final ApplicationPermissionValueSet permissionSet;
-    
+
     public boolean isDisabled() {
         return getStatus() == ApplicationUserStatus.DISABLED;
     }
@@ -95,7 +95,7 @@ class PrincipalForApplicationUser implements AuthorizationInfo {
     public Collection<String> getStringPermissions() {
         return Collections.emptyList();
     }
-    
+
     @Override
     public Collection<Permission> getObjectPermissions() {
         return objectPermissions.get();
@@ -112,22 +112,22 @@ class PrincipalForApplicationUser implements AuthorizationInfo {
     public String toString() {
         return getUsername();
     }
-    
+
     // -- HELPER
-    
-    private final transient _Lazy<Collection<Permission>> objectPermissions = 
+
+    private final transient _Lazy<Collection<Permission>> objectPermissions =
             _Lazy.threadSafe(this::createObjectPermissions);
-    
+
     private Collection<Permission> createObjectPermissions() {
         val permission = Permission_backedByPermissionSet.of(getPermissionSet());
         return Collections.singleton(permission);
     }
-    
+
     @RequiredArgsConstructor(staticName = "of")
     private static class Permission_backedByPermissionSet implements Permission {
-        
+
         @NonNull private final ApplicationPermissionValueSet permissionSet;
-        
+
         @Override
         public boolean implies(Permission p) {
             if (!(p instanceof PermissionForMember)) {
@@ -135,9 +135,9 @@ class PrincipalForApplicationUser implements AuthorizationInfo {
             }
             val permissionForMember = (PermissionForMember) p;
             return permissionSet.grants(
-                    permissionForMember.getFeatureId(), 
+                    permissionForMember.getFeatureId(),
                     permissionForMember.getMode());
         }
     }
-    
+
 }