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/07 05:47:59 UTC

[isis] 01/01: gonna abandon this branch - it's too big. But I think I now know the patterns to refactor to

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

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

commit 7ec012a0a8b2303b1bf9d592c7c607dff09119f4
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Fri May 7 06:47:19 2021 +0100

    gonna abandon this branch - it's too big.  But I think I now know the patterns to refactor to
---
 .../secman/api/IsisModuleExtSecmanApi.java         |  17 +--
 .../secman/api/authorizor/AuthorizorSecman.java    |   2 +-
 .../api/permission/ApplicationPermission.java      |  33 ++++--
 .../ApplicationPermissionRepository.java           |  26 ++---
 ...or.java => ApplicationPermissionUiAdvisor.java} |   5 +-
 .../secman/api/role/ApplicationRole.java           |  16 +--
 .../secman/api/role/ApplicationRoleRepository.java |  21 ++--
 ...eAdvisor.java => ApplicationRoleUiAdvisor.java} |   5 +-
 .../secman/api/tenancy/ApplicationTenancy.java     |  42 ++++---
 .../api/tenancy/ApplicationTenancyRepository.java  |  14 +--
 .../ApplicationTenancyRepositoryAbstract.java}     | 127 +++++++++------------
 .../secman/api/user/ApplicationUser.java           |  26 +++--
 .../api/user/ApplicationUserIconAdvisor.java       |  25 ----
 .../secman/api/user/ApplicationUserRepository.java |  28 ++---
 ...eAdvisor.java => ApplicationUserUiAdvisor.java} |  20 +++-
 .../dom/feature/ApplicationFeatureViewModel.java   |  10 +-
 .../ApplicationOrphanedPermissionManager.java      |  10 +-
 .../dom/permission/ApplicationPermissionMenu.java  |   2 +-
 .../ApplicationPermission_updateRole.java          |   2 +-
 .../secman/model/dom/role/ApplicationRoleMenu.java |   2 +-
 .../dom/role/ApplicationRole_addPermission.java    |   2 +-
 .../model/dom/role/ApplicationRole_addUser.java    |   9 +-
 .../model/dom/role/ApplicationRole_delete.java     |   2 +-
 .../role/ApplicationRole_removePermissions.java    |   2 +-
 .../dom/role/ApplicationRole_removeUsers.java      |   4 +-
 .../model/dom/tenancy/ApplicationTenancyMenu.java  |   2 +-
 .../dom/tenancy/ApplicationTenancy_addChild.java   |   8 +-
 .../dom/tenancy/ApplicationTenancy_addUser.java    |  10 +-
 .../dom/tenancy/ApplicationTenancy_delete.java     |  14 +--
 .../tenancy/ApplicationTenancy_removeChild.java    |  12 +-
 .../dom/tenancy/ApplicationTenancy_removeUser.java |  18 +--
 .../tenancy/ApplicationTenancy_updateParent.java   |  10 +-
 .../dom/tenancy/ApplicationTenancy_users.java      |   8 +-
 .../model/dom/user/ApplicationUserManager.java     |  10 +-
 .../dom/user/ApplicationUserManager_allUsers.java  |  22 ++--
 .../ApplicationUserManager_newDelegateUser.java    |  10 +-
 .../user/ApplicationUserManager_newLocalUser.java  |  12 +-
 .../secman/model/dom/user/ApplicationUserMenu.java |  21 ++--
 .../model/dom/user/ApplicationUser_addRole.java    |   3 +-
 .../model/dom/user/ApplicationUser_delete.java     |   2 +-
 .../model/dom/user/ApplicationUser_duplicate.java  |   4 +-
 .../model/dom/user/ApplicationUser_lock.java       |   2 +-
 .../dom/user/ApplicationUser_removeRoles.java      |   4 +-
 .../dom/user/ApplicationUser_resetPassword.java    |   2 +-
 .../user/ApplicationUser_updateAccountType.java    |   2 +-
 .../dom/user/ApplicationUser_updatePassword.java   |   2 +-
 .../secman/model/dom/user/HasUsername_open.java    |   4 +-
 .../secman/model/dom/user/MeService.java           |   8 +-
 .../model/dom/user/UserPermissionViewModel.java    |  42 +++----
 .../facets/TenantedAuthorizationFacetDefault.java  |   4 +-
 .../facets/TenantedAuthorizationPostProcessor.java |   2 +-
 .../menu/ImpersonateMenuAdvisorForSecman.java      |   4 +-
 .../jdo/dom/permission/ApplicationPermission.java  |  25 ++--
 .../ApplicationPermissionRepository.java           |  84 +++++++++-----
 .../secman/jdo/dom/role/ApplicationRole.java       |   6 +-
 .../jdo/dom/role/ApplicationRoleRepository.java    |  35 +++---
 .../secman/jdo/dom/tenancy/ApplicationTenancy.java |   6 +-
 .../dom/tenancy/ApplicationTenancyRepository.java  |  91 ++++++++-------
 .../secman/jdo/dom/user/ApplicationUser.java       |   6 +-
 .../dom/user/ApplicationUserManager_allUsers.java  |   9 +-
 .../ApplicationUserManager_newDelegateUser.java    |   4 +-
 .../user/ApplicationUserManager_newLocalUser.java  |   4 +-
 .../jdo/dom/user/ApplicationUserRepository.java    |  78 ++++++++++---
 .../jpa/dom/permission/ApplicationPermission.java  |  24 ++--
 .../ApplicationPermissionRepository.java           |  46 ++++----
 .../secman/jpa/dom/role/ApplicationRole.java       |   7 +-
 .../jpa/dom/role/ApplicationRoleRepository.java    |  34 +++---
 .../secman/jpa/dom/tenancy/ApplicationTenancy.java |   9 +-
 .../dom/tenancy/ApplicationTenancyRepository.java  |  18 +--
 .../secman/jpa/dom/user/ApplicationUser.java       |   7 +-
 .../jpa/dom/user/ApplicationUserRepository.java    |  10 +-
 .../shiro/IsisModuleExtSecmanShiroRealm.java       |   4 +-
 72 files changed, 638 insertions(+), 563 deletions(-)

diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/IsisModuleExtSecmanApi.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/IsisModuleExtSecmanApi.java
index 03ae96d..8d3da4a 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/IsisModuleExtSecmanApi.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/IsisModuleExtSecmanApi.java
@@ -21,20 +21,21 @@ package org.apache.isis.extensions.secman.api;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionTitleAdvisor;
-import org.apache.isis.extensions.secman.api.role.ApplicationRoleTitleAdvisor;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserIconAdvisor;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserTitleAdvisor;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionUiAdvisor;
+import org.apache.isis.extensions.secman.api.role.ApplicationRoleUiAdvisor;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
+import org.apache.isis.extensions.secman.api.user.ApplicationUserUiAdvisor;
 
 /**
  * @since 2.0 {@index}
  */
 @Configuration()
 @Import({
-        ApplicationPermissionTitleAdvisor.class,
-        ApplicationUserTitleAdvisor.class,
-        ApplicationUserIconAdvisor.class,
-        ApplicationRoleTitleAdvisor.class,
+        ApplicationPermissionUiAdvisor.class,
+        ApplicationUserUiAdvisor.class,
+        ApplicationRoleUiAdvisor.class,
+
+        ApplicationUser.HasPasswordAdvisor.class,
 })
 public class IsisModuleExtSecmanApi {
 
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/authorizor/AuthorizorSecman.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/authorizor/AuthorizorSecman.java
index f49b996..9c1ce07 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/authorizor/AuthorizorSecman.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/authorizor/AuthorizorSecman.java
@@ -43,7 +43,7 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 @Qualifier("Secman")
 public class AuthorizorSecman implements Authorizor {
 
-    @Inject ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject ApplicationUserRepository applicationUserRepository;
 
     @Override
     public boolean isVisible(final Authentication authentication, final Identifier identifier) {
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 d044578..fb341d9 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
@@ -27,6 +27,7 @@ import java.util.Optional;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
@@ -78,21 +79,21 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUser;
         cssClassUiEvent = ApplicationPermission.CssClassUiEvent.class,
         layoutUiEvent = ApplicationPermission.LayoutUiEvent.class
 )
-public interface ApplicationPermission<APPUSER extends ApplicationUser<APPUSER,APPROLE>, APPROLE extends ApplicationRole<APPUSER, APPROLE>> {
+public interface ApplicationPermission extends Comparable<ApplicationPermission>{
 
 
     // -- DOMAIN EVENTS
 
-    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationPermission<?,?>, T> {}
-    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermission<?,?>, T> {}
+    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationPermission, T> {}
+    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermission, T> {}
 
 
     // -- UI EVENTS
 
-    class TitleUiEvent extends IsisModuleExtSecmanApi.TitleUiEvent<ApplicationPermission<?,?>> {}
-    class IconUiEvent extends IsisModuleExtSecmanApi.IconUiEvent<ApplicationPermission<?,?>> {}
-    class CssClassUiEvent extends IsisModuleExtSecmanApi.CssClassUiEvent<ApplicationPermission<?,?>> {}
-    class LayoutUiEvent extends IsisModuleExtSecmanApi.LayoutUiEvent<ApplicationPermission<?,?>> {}
+    class TitleUiEvent extends IsisModuleExtSecmanApi.TitleUiEvent<ApplicationPermission> {}
+    class IconUiEvent extends IsisModuleExtSecmanApi.IconUiEvent<ApplicationPermission> {}
+    class CssClassUiEvent extends IsisModuleExtSecmanApi.CssClassUiEvent<ApplicationPermission> {}
+    class LayoutUiEvent extends IsisModuleExtSecmanApi.LayoutUiEvent<ApplicationPermission> {}
 
 
 
@@ -110,27 +111,33 @@ public interface ApplicationPermission<APPUSER extends ApplicationUser<APPUSER,A
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
     @interface Role {
-        class DomainEvent extends PropertyDomainEvent<ApplicationRole<?,?>> {}
+        class DomainEvent extends PropertyDomainEvent<ApplicationRole> {}
     }
 
     @Role
-    APPROLE getRole();
-    void setRole(APPROLE applicationRole);
+    ApplicationRole getRole();
+    void setRole(ApplicationRole applicationRole);
 
 
     // -- FEATURE FQN
 
     @Property(
             domainEvent = FeatureFqn.DomainEvent.class,
-            editing = Editing.DISABLED
+            editing = Editing.DISABLED,
+            maxLength = FeatureFqn.MAX_LENGTH
     )
     @PropertyLayout(
             fieldSetId="identity",
             sequence = "2"
     )
+    @Parameter(
+            maxLength = FeatureFqn.MAX_LENGTH
+    )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
     @interface FeatureFqn {
+        int MAX_LENGTH = 1024;
+
         class DomainEvent extends PropertyDomainEvent<String> {}
     }
 
@@ -170,6 +177,9 @@ public interface ApplicationPermission<APPUSER extends ApplicationUser<APPUSER,A
             fieldSetId="feature",
             sequence = "1"
     )
+    @Parameter(
+            maxLength = Sort.MAX_LENGTH
+    )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
     @interface Sort {
@@ -228,7 +238,6 @@ public interface ApplicationPermission<APPUSER extends ApplicationUser<APPUSER,A
 
 
 
-
     // -- HELPER
 
     @Programmatic
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java
index f78213e..1072837 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java
@@ -28,21 +28,21 @@ import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 /**
  * @since 2.0 {@index}
  */
-public interface ApplicationPermissionRepository<P extends ApplicationPermission> {
+public interface ApplicationPermissionRepository {
 
-    Optional<P> findByUserAndPermissionValue(String username, ApplicationPermissionValue changingPermissionValue);
+    Optional<ApplicationPermission> findByUserAndPermissionValue(String username, ApplicationPermissionValue changingPermissionValue);
 
-    Optional<P> findByRoleAndRuleAndFeature(
+    Optional<ApplicationPermission> findByRoleAndRuleAndFeature(
             ApplicationRole holder,
             ApplicationPermissionRule rule,
             ApplicationFeatureSort type,
             String featureFqn);
 
-    Collection<P> allPermissions();
+    Collection<ApplicationPermission> allPermissions();
 
-    Collection<P> findOrphaned();
-    Collection<P> findByFeatureCached(ApplicationFeatureId featureId);
-    Collection<P> findByRoleAndRuleAndFeatureTypeCached(
+    Collection<ApplicationPermission> findOrphaned();
+    Collection<ApplicationPermission> findByFeatureCached(ApplicationFeatureId featureId);
+    Collection<ApplicationPermission> findByRoleAndRuleAndFeatureTypeCached(
             ApplicationRole holder,
             ApplicationPermissionRule rule,
             ApplicationFeatureSort type);
@@ -51,9 +51,9 @@ public interface ApplicationPermissionRepository<P extends ApplicationPermission
     /**
      * @return detached entity
      */
-    P newApplicationPermission();
+    ApplicationPermission newApplicationPermission();
 
-    P newPermission(
+    ApplicationPermission newPermission(
             ApplicationRole role,
             ApplicationPermissionRule rule,
             ApplicationPermissionMode mode,
@@ -61,18 +61,18 @@ public interface ApplicationPermissionRepository<P extends ApplicationPermission
             String className,
             String memberName);
 
-    P newPermission(
+    ApplicationPermission newPermission(
             ApplicationRole role,
             ApplicationPermissionRule rule,
             ApplicationPermissionMode mode,
             ApplicationFeatureSort featureSort,
             String featureFqn);
 
-    P newPermission(
+    ApplicationPermission newPermission(
             ApplicationRole role,
             ApplicationPermissionRule rule,
             ApplicationPermissionMode mode,
             ApplicationFeatureId featureId);
-    
-    
+
+
 }
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionTitleAdvisor.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionUiAdvisor.java
similarity index 95%
rename from extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionTitleAdvisor.java
rename to extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionUiAdvisor.java
index f6f68a0..17376f8 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionTitleAdvisor.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionUiAdvisor.java
@@ -11,11 +11,14 @@ import lombok.val;
 @Component
 @Order(OrderPrecedence.LATE)
 public
-class ApplicationPermissionTitleAdvisor {
+class ApplicationPermissionUiAdvisor {
 
     @EventListener(ApplicationPermission.TitleUiEvent.class)
     public void on(ApplicationPermission.TitleUiEvent ev) {
         val permission = ev.getSource();
+        if(permission == null) {
+            return;
+        }
         val buf = new StringBuilder();
         buf.append(permission.getRole().getName()).append(":")  // admin:
                 .append(" ").append(permission.getRule().toString()) // Allow|Veto
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 e4144b8..c49a1cc 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,7 +35,7 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUser;
         cssClassUiEvent = ApplicationRole.CssClassUiEvent.class,
         layoutUiEvent = ApplicationRole.LayoutUiEvent.class
 )
-public interface ApplicationRole<APPUSER extends ApplicationUser<APPUSER,APPROLE>, APPROLE extends ApplicationRole<APPUSER, APPROLE>> extends Comparable<APPROLE>{
+public interface ApplicationRole extends Comparable<ApplicationRole>{
 
     int MAX_LENGTH_NAME = 120;
     int TYPICAL_LENGTH_NAME = 30;
@@ -43,14 +43,14 @@ public interface ApplicationRole<APPUSER extends ApplicationUser<APPUSER,APPROLE
 
     // -- EVENTS
 
-    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationRole<?,?>, T> {}
-    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationRole<?,?>, T> {}
-    abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole<?,?>> {}
+    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationRole, T> {}
+    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationRole, T> {}
+    abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole> {}
 
-    class TitleUiEvent extends IsisModuleExtSecmanApi.TitleUiEvent<ApplicationRole<?,?>> {}
-    class IconUiEvent extends IsisModuleExtSecmanApi.IconUiEvent<ApplicationRole<?,?>> {}
-    class CssClassUiEvent extends IsisModuleExtSecmanApi.CssClassUiEvent<ApplicationRole<?,?>> {}
-    class LayoutUiEvent extends IsisModuleExtSecmanApi.LayoutUiEvent<ApplicationRole<?,?>> {}
+    class TitleUiEvent extends IsisModuleExtSecmanApi.TitleUiEvent<ApplicationRole> {}
+    class IconUiEvent extends IsisModuleExtSecmanApi.IconUiEvent<ApplicationRole> {}
+    class CssClassUiEvent extends IsisModuleExtSecmanApi.CssClassUiEvent<ApplicationRole> {}
+    class LayoutUiEvent extends IsisModuleExtSecmanApi.LayoutUiEvent<ApplicationRole> {}
 
 
     // -- MODEL
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleRepository.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleRepository.java
index da3e1e7..692b6dc 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleRepository.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleRepository.java
@@ -26,31 +26,30 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 /**
  * @since 2.0 {@index}
  */
-public interface ApplicationRoleRepository<R extends ApplicationRole> {
+public interface ApplicationRoleRepository {
 
     /**
      *
      * @return detached entity
      */
-    R newApplicationRole();
+    ApplicationRole newApplicationRole();
 
-    Collection<R> allRoles();
+    Collection<ApplicationRole> allRoles();
 
-    R newRole(String name, String description);
+    ApplicationRole newRole(String name, String description);
 
-    Collection<R> findNameContaining(String search);
-    Collection<R> getRoles(ApplicationUser user);
+    Collection<ApplicationRole> findNameContaining(String search);
 
     /**
      * auto-complete support
      * @param search
      */
-    Collection<R> findMatching(String search);
+    Collection<ApplicationRole> findMatching(String search);
 
-    Optional<R> findByName(String roleName);
-    Optional<R> findByNameCached(String roleName);
+    Optional<ApplicationRole> findByName(String roleName);
+    Optional<ApplicationRole> findByNameCached(String roleName);
 
-    default R upsert(final String name, final String roleDescription) {
+    default ApplicationRole upsert(final String name, final String roleDescription) {
         return findByName(name)
                 .orElseGet(() -> newRole(name, roleDescription));
     }
@@ -62,6 +61,4 @@ public interface ApplicationRoleRepository<R extends ApplicationRole> {
 
     void deleteRole(ApplicationRole holder);
 
-
-
 }
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleTitleAdvisor.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleUiAdvisor.java
similarity index 87%
rename from extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleTitleAdvisor.java
rename to extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleUiAdvisor.java
index 49ffb60..2eef7b0 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleTitleAdvisor.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/role/ApplicationRoleUiAdvisor.java
@@ -12,11 +12,14 @@ import lombok.val;
 @Component
 @Order(OrderPrecedence.LATE)
 public
-class ApplicationRoleTitleAdvisor {
+class ApplicationRoleUiAdvisor {
 
     @EventListener(ApplicationRole.TitleUiEvent.class)
     public void on(ApplicationRole.TitleUiEvent ev) {
         val role = ev.getSource();
+        if(role == null) {
+            return;
+        }
         ev.setTitle(role.getName());
     }
 
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 ed209ea..7426436 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
@@ -18,30 +18,33 @@
  */
 package org.apache.isis.extensions.secman.api.tenancy;
 
+import java.util.Collection;
+
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 
 /**
  * @since 2.0 {@index}
  */
-public interface ApplicationTenancy {
+public interface ApplicationTenancy extends Comparable<ApplicationTenancy> {
+
+    int MAX_LENGTH_PATH = 255;
+    int MAX_LENGTH_NAME = 120;
+    int TYPICAL_LENGTH_NAME = 20;
 
-    public static final int MAX_LENGTH_PATH = 255;
-    public static final int MAX_LENGTH_NAME = 120;
-    public static final int TYPICAL_LENGTH_NAME = 20;
 
     // -- DOMAIN EVENTS
 
-    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationTenancy, T> {}
-    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationTenancy, T> {}
-    public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationTenancy, T> {}
+    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationTenancy, T> {}
+    abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
 
-    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> {}
+    class AddUserDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    class RemoveUserDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    class AddChildDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    class DeleteDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    class RemoveChildDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    class UpdateNameDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
+    class UpdateParentDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancy> {}
 
     // -- MODEL
 
@@ -49,12 +52,15 @@ public interface ApplicationTenancy {
         return getName();
     }
 
-    public String getPath();
+    String getPath();
+    void setPath(String path);
 
-    public String getName();
-    public void setName(String name);
+    String getName();
+    void setName(String name);
 
-    public ApplicationTenancy getParent();
+    ApplicationTenancy getParent();
+    void setParent(ApplicationTenancy parent);
 
+    Collection<ApplicationTenancy> getChildren();
 
 }
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepository.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepository.java
index 7afbe7f..7358777 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepository.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepository.java
@@ -25,25 +25,25 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 /**
  * @since 2.0 {@index}
  */
-public interface ApplicationTenancyRepository<T extends ApplicationTenancy> {
+public interface ApplicationTenancyRepository {
 
     /**
      *
      * @return detached entity
      */
-    T newApplicationTenancy();
+    ApplicationTenancy newApplicationTenancy();
 
-    Collection<T> allTenancies();
-    Collection<T> getChildren(ApplicationTenancy tenancy);
-    Collection<T> findByNameOrPathMatchingCached(String partialNameOrPath);
+    Collection<ApplicationTenancy> allTenancies();
+    Collection<ApplicationTenancy> getChildren(ApplicationTenancy tenancy);
+    Collection<ApplicationTenancy> findByNameOrPathMatchingCached(String partialNameOrPath);
 
     /**
      * auto-complete support
      * @param search
      */
-    Collection<T> findMatching(String search);
+    Collection<ApplicationTenancy> findMatching(String search);
 
-    T newTenancy(String name, String path, ApplicationTenancy parent);
+    ApplicationTenancy newTenancy(String name, String path, ApplicationTenancy parent);
 
     void setTenancyOnUser(ApplicationTenancy tenancy, ApplicationUser user);
     void clearTenancyOnUser(ApplicationUser user);
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepositoryAbstract.java
similarity index 50%
copy from extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java
copy to extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepositoryAbstract.java
index d442b94..050460f 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/tenancy/ApplicationTenancyRepositoryAbstract.java
@@ -16,98 +16,99 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.secman.jdo.dom.tenancy;
+package org.apache.isis.extensions.secman.api.tenancy;
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.concurrent.Callable;
 
 import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.springframework.stereotype.Repository;
 
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.extensions.secman.jdo.dom.user.ApplicationUser;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 
 import lombok.NonNull;
-import lombok.val;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public abstract class ApplicationTenancyRepositoryAbstract<T extends ApplicationTenancy>
+implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepository {
 
-@Repository
-@Named("isis.ext.secman.ApplicationTenancyRepository")
-public class ApplicationTenancyRepository
-implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepository<ApplicationTenancy> {
+    private final Class<T> applicationTenancyClass;
 
     @Inject private FactoryService factory;
     @Inject private RepositoryService repository;
-
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
     @Override
     public ApplicationTenancy newApplicationTenancy() {
-        return factory.detachedEntity(new ApplicationTenancy());
+        return factory.detachedEntity(applicationTenancyClass);
     }
 
+
     // -- findByNameOrPathMatching
 
     @Override
     public Collection<ApplicationTenancy> findByNameOrPathMatchingCached(final String search) {
-        return queryResultsCacheProvider.get().execute(new Callable<Collection<ApplicationTenancy>>() {
-            @Override public Collection<ApplicationTenancy> call() throws Exception {
-                return findByNameOrPathMatching(search);
-            }
-        }, ApplicationTenancyRepository.class, "findByNameOrPathMatchingCached", search);
+        return queryResultsCacheProvider.get().execute(
+                () -> findByNameOrPathMatching(search),
+                ApplicationTenancyRepositoryAbstract.class,
+                "findByNameOrPathMatchingCached", search);
     }
 
-    public Collection<ApplicationTenancy> findByNameOrPathMatching(final String search) {
-        if (search == null) {
+    private Collection<ApplicationTenancy> findByNameOrPathMatching(final String search) {
+        if (_Strings.isNullOrEmpty(search)) {
             return Collections.emptySortedSet();
         }
-        return repository.allMatches(Query.named(ApplicationTenancy.class, "findByNameOrPathMatching")
-                .withParameter("regex", String.format("(?i).*%s.*", search.replace("*", ".*").replace("?", "."))))
+        return repository.allMatches(
+                Query.named(applicationTenancyClass, "findByNameOrPathMatching")
+                    .withParameter("regex", regexified(search)))
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
+    private static String regexified(String search) {
+        return String.format("(?i).*%s.*", search.replace("*", ".*").replace("?", "."));
+    }
+
+
     // -- findByName
 
     public ApplicationTenancy findByNameCached(final String name) {
-        return queryResultsCacheProvider.get().execute(new Callable<ApplicationTenancy>() {
-            @Override
-            public ApplicationTenancy call() throws Exception {
-                return findByName(name);
-            }
-        }, ApplicationTenancyRepository.class, "findByNameCached", name);
+        return queryResultsCacheProvider.get().execute(
+                () -> findByName(name),
+                ApplicationTenancyRepositoryAbstract.class,
+                "findByNameCached", name);
     }
 
     public ApplicationTenancy findByName(final String name) {
-        return repository.uniqueMatch(Query.named(ApplicationTenancy.class, "findByName")
-                .withParameter("name", name)).orElse(null);
+        return repository.uniqueMatch(
+                    Query.named(applicationTenancyClass, "findByName")
+                         .withParameter("name", name))
+                .orElse(null);
     }
 
 
     // -- findByPath
 
     public ApplicationTenancy findByPathCached(final String path) {
-        return queryResultsCacheProvider.get().execute(new Callable<ApplicationTenancy>() {
-            @Override
-            public ApplicationTenancy call() throws Exception {
-                return findByPath(path);
-            }
-        }, ApplicationTenancyRepository.class, "findByPathCached", path);
+        return queryResultsCacheProvider.get().execute(
+                () -> findByPath(path),
+                ApplicationTenancyRepositoryAbstract.class,
+                "findByPathCached", path);
     }
 
     public ApplicationTenancy findByPath(final String path) {
         if (path == null) {
             return null;
         }
-        return repository.uniqueMatch(Query.named(ApplicationTenancy.class, "findByPath")
-                .withParameter("path", path))
+        return repository.uniqueMatch(
+                    Query.named(applicationTenancyClass, "findByPath")
+                         .withParameter("path", path))
                 .orElse(null);
     }
 
@@ -115,10 +116,10 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
     // -- autoComplete
     @Override
     public Collection<ApplicationTenancy> findMatching(final String search) {
-        if (search != null && search.length() > 0) {
-            return findByNameOrPathMatching(search);
+        if (_Strings.isNullOrEmpty(search)) {
+            return Collections.emptySortedSet();
         }
-        return Collections.emptySortedSet();
+        return findByNameOrPathMatching(search);
     }
 
     // -- newTenancy
@@ -127,18 +128,17 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
     public ApplicationTenancy newTenancy(
             final String name,
             final String path,
-            final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy parent) {
+            final ApplicationTenancy parent) {
         ApplicationTenancy tenancy = findByPath(path);
         if (tenancy == null) {
             tenancy = newApplicationTenancy();
             tenancy.setName(name);
             tenancy.setPath(path);
-            final ApplicationTenancy parentJdo = (ApplicationTenancy) parent;
-            tenancy.setParent(parentJdo);
-            if(parentJdo != null) {
+            tenancy.setParent(parent);
+            if(parent != null) {
                 // although explicit maintenance of the children is normally not needed,
                 // DN 5.x by default logs a warning if it discovers a mismatch; this quietens that
-                parentJdo.getChildren().add(tenancy);
+                parent.getChildren().add(tenancy);
             }
             repository.persist(tenancy);
         }
@@ -149,45 +149,34 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
 
     @Override
     public Collection<ApplicationTenancy> allTenancies() {
-        return queryResultsCacheProvider.get().execute(new Callable<Collection<ApplicationTenancy>>() {
-            @Override
-            public Collection<ApplicationTenancy> call() throws Exception {
-                return allTenanciesNoCache();
-            }
-        }, ApplicationTenancyRepository.class, "allTenancies");
+        return queryResultsCacheProvider.get().execute(
+                this::allTenanciesNoCache,
+                ApplicationTenancyRepositoryAbstract.class, "allTenancies");
     }
 
     public Collection<ApplicationTenancy> allTenanciesNoCache() {
         return repository.allInstances(ApplicationTenancy.class)
                 .stream()
-                .map(ApplicationTenancy.class::cast)
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
     @Override
     public void setTenancyOnUser(
-            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy,
-            @NonNull final org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
-        val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
-        val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
-        // no need to add to users set, since will be done by JDO/DN.
+            @NonNull final ApplicationTenancy tenancy,
+            @NonNull final ApplicationUser user) {
         user.setAtPath(tenancy.getPath());
     }
 
     @Override
     public void clearTenancyOnUser(
-            @NonNull final org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
-        val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
-        // no need to remove from users set, since will be done by JDO/DN.
+            @NonNull final ApplicationUser user) {
         user.setAtPath(null);
     }
 
     @Override
     public void setParentOnTenancy(
-            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy,
-            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericParent) {
-        val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
-        val parent = _Casts.<ApplicationTenancy>uncheckedCast(genericParent);
+            @NonNull final ApplicationTenancy tenancy,
+            @NonNull final ApplicationTenancy parent) {
         // although explicit maintenance of the children is normally not needed,
         // DN 5.x by default logs a warning if it discovers a mismatch; this quietens that
         tenancy.setParent(parent);
@@ -196,8 +185,7 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
 
     @Override
     public void clearParentOnTenancy(
-            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
-        val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
+            @NonNull final ApplicationTenancy tenancy) {
         // although explicit maintenance of the children is normally not needed,
         // DN 5.x by default logs a warning if it discovers a mismatch; this quietens that
         final ApplicationTenancy parent = tenancy.getParent();
@@ -209,8 +197,7 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
 
     @Override
     public Collection<ApplicationTenancy> getChildren(
-            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
-        val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
+            @NonNull final ApplicationTenancy tenancy) {
         return tenancy.getChildren()
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
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 2b688f9..fca248c 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
@@ -27,6 +27,7 @@ import java.util.Set;
 import javax.inject.Inject;
 
 import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.Collection;
@@ -34,6 +35,7 @@ import org.apache.isis.applib.annotation.CollectionLayout;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
@@ -42,7 +44,6 @@ 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.ApplicationPermission;
 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;
@@ -61,21 +62,21 @@ import lombok.RequiredArgsConstructor;
         cssClassUiEvent = ApplicationUser.CssClassUiEvent.class,
         layoutUiEvent = ApplicationUser.LayoutUiEvent.class
 )
-public interface ApplicationUser<APPUSER extends ApplicationUser<APPUSER,APPROLE>, APPROLE extends ApplicationRole<APPUSER, APPROLE>>
-        extends HasUsername, HasAtPath, Comparable<APPUSER> {
+public interface ApplicationUser
+        extends HasUsername, HasAtPath, Comparable<ApplicationUser> {
 
 
     // -- DOMAIN EVENTS
 
-    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationUser<?,?>, T> {}
-    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationUser<?,?>, T> {}
+    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationUser, T> {}
+    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationUser, T> {}
 
     // -- UI EVENTS
 
-    class TitleUiEvent extends IsisModuleExtSecmanApi.TitleUiEvent<ApplicationUser<?,?>> {}
-    class IconUiEvent extends IsisModuleExtSecmanApi.IconUiEvent<ApplicationUser<?,?>> {}
-    class CssClassUiEvent extends IsisModuleExtSecmanApi.CssClassUiEvent<ApplicationUser<?,?>> {}
-    class LayoutUiEvent extends IsisModuleExtSecmanApi.LayoutUiEvent<ApplicationUser<?,?>> {}
+    class TitleUiEvent extends IsisModuleExtSecmanApi.TitleUiEvent<ApplicationUser> {}
+    class IconUiEvent extends IsisModuleExtSecmanApi.IconUiEvent<ApplicationUser> {}
+    class CssClassUiEvent extends IsisModuleExtSecmanApi.CssClassUiEvent<ApplicationUser> {}
+    class LayoutUiEvent extends IsisModuleExtSecmanApi.LayoutUiEvent<ApplicationUser> {}
 
 
 
@@ -378,13 +379,15 @@ public interface ApplicationUser<APPUSER extends ApplicationUser<APPUSER,APPROLE
 
 
     @Component
+    @Order(OrderPrecedence.LATE)
     @RequiredArgsConstructor(onConstructor_ = {@Inject})
     class HasPasswordAdvisor {
 
-        final org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<?> applicationUserRepository;
+        final org.apache.isis.extensions.secman.api.user.ApplicationUserRepository applicationUserRepository;
 
         @EventListener(HasPassword.DomainEvent.class)
         public void advise(HasPassword.DomainEvent ev) {
+            //noinspection SwitchStatementWithTooFewBranches
             switch(ev.getEventPhase()) {
                 case HIDE:
                     if(! applicationUserRepository.isPasswordFeatureEnabled(ev.getSource())) {
@@ -415,14 +418,13 @@ public interface ApplicationUser<APPUSER extends ApplicationUser<APPUSER,APPROLE
     }
 
     @Roles
-    Set<APPROLE> getRoles();
+    Set<ApplicationRole> getRoles();
 
 
 
 
     /**
      * Short-term (request-scoped) caching.
-     * @return
      */
     @Programmatic
     ApplicationPermissionValueSet getPermissionSet();
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserIconAdvisor.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserIconAdvisor.java
deleted file mode 100644
index 51970aa..0000000
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserIconAdvisor.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.apache.isis.extensions.secman.api.user;
-
-import org.springframework.context.event.EventListener;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.OrderPrecedence;
-
-import lombok.val;
-
-@Component
-@Order(OrderPrecedence.LATE)
-public
-class ApplicationUserIconAdvisor {
-
-    @EventListener(ApplicationUser.IconUiEvent.class)
-    public void on(ApplicationUser.IconUiEvent ev) {
-        val user = ev.getSource();
-        ev.setIconName(
-                user.getStatus().isEnabled()
-                        ? "enabled"
-                        : "disabled");
-    }
-
-}
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserRepository.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserRepository.java
index 791620b..99d5500 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserRepository.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserRepository.java
@@ -33,27 +33,27 @@ import lombok.NonNull;
 /**
  * @since 2.0 {@index}
  */
-public interface ApplicationUserRepository<U extends ApplicationUser> {
+public interface ApplicationUserRepository {
 
     /**
      * @return detached entity
      */
-    U newApplicationUser();
+    ApplicationUser newApplicationUser();
 
-    Optional<U> findByUsername(String username);
-    U findOrCreateUserByUsername(String username);
+    Optional<ApplicationUser> findByUsername(String username);
+    ApplicationUser findOrCreateUserByUsername(String username);
 
-    Collection<U> allUsers();
-    Collection<U> find(String search);
-    Collection<U> findByAtPath(String atPath);
-    Collection<U> findByRole(ApplicationRole role);
-    Collection<U> findByTenancy(ApplicationTenancy tenancy);
+    Collection<ApplicationUser> allUsers();
+    Collection<ApplicationUser> find(String search);
+    Collection<ApplicationUser> findByAtPath(String atPath);
+    Collection<ApplicationUser> findByRole(ApplicationRole role);
+    Collection<ApplicationUser> findByTenancy(ApplicationTenancy tenancy);
 
     /**
      * auto-complete support
      * @param search
      */
-    Collection<U> findMatching(String search);
+    Collection<ApplicationUser> findMatching(String search);
 
     void enable(ApplicationUser user);
     void disable(ApplicationUser user);
@@ -63,9 +63,9 @@ public interface ApplicationUserRepository<U extends ApplicationUser> {
 
     boolean updatePassword(ApplicationUser user, String password);
 
-    U newUser(String username, AccountType accountType, Consumer<U> beforePersist);
+    ApplicationUser newUser(String username, AccountType accountType, Consumer<ApplicationUser> beforePersist);
 
-    default U upsertLocal(
+    default ApplicationUser upsertLocal(
             @NonNull String username,
             @Nullable Password password,
             @NonNull ApplicationUserStatus status) {
@@ -73,7 +73,7 @@ public interface ApplicationUserRepository<U extends ApplicationUser> {
                 .orElseGet(() -> newLocalUser(username, password, status));
     }
 
-    default U newLocalUser(
+    default ApplicationUser newLocalUser(
             @NonNull String username,
             @Nullable Password password,
             @NonNull ApplicationUserStatus status) {
@@ -89,7 +89,7 @@ public interface ApplicationUserRepository<U extends ApplicationUser> {
         });
     }
 
-    default U newDelegateUser(
+    default ApplicationUser newDelegateUser(
             String username,
             ApplicationUserStatus status) {
 
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserTitleAdvisor.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserUiAdvisor.java
similarity index 67%
rename from extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserTitleAdvisor.java
rename to extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserUiAdvisor.java
index 164730a..1251fa5 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserTitleAdvisor.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUserUiAdvisor.java
@@ -5,18 +5,20 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 
 import lombok.val;
 
 @Component
 @Order(OrderPrecedence.LATE)
 public
-class ApplicationUserTitleAdvisor {
+class ApplicationUserUiAdvisor {
 
     @EventListener(ApplicationUser.TitleUiEvent.class)
     public void on(ApplicationUser.TitleUiEvent ev) {
         val user = ev.getSource();
+        if(user == null) {
+            return;
+        }
 
         val buf = new StringBuilder();
         if(user.getFamilyName() != null) {
@@ -24,7 +26,7 @@ class ApplicationUserTitleAdvisor {
                     user.getKnownAs() != null
                             ? user.getKnownAs()
                             : user.getGivenName())
-               .append(' ')
+                    .append(' ')
                     .append(user.getFamilyName())
                     .append(" (").append(user.getUsername()).append(')');
         } else {
@@ -33,4 +35,16 @@ class ApplicationUserTitleAdvisor {
         ev.setTitle(buf.toString());
     }
 
+    @EventListener(ApplicationUser.IconUiEvent.class)
+    public void on(ApplicationUser.IconUiEvent ev) {
+        val user = ev.getSource();
+        if(user == null) {
+            return;
+        }
+        ev.setIconName(
+                user.getStatus().isEnabled()
+                        ? "enabled"
+                        : "disabled");
+    }
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/feature/ApplicationFeatureViewModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/feature/ApplicationFeatureViewModel.java
index 39e8e77..c54f602 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/feature/ApplicationFeatureViewModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/feature/ApplicationFeatureViewModel.java
@@ -61,7 +61,7 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
 
     @Inject private FactoryService factory;
     @Inject private ApplicationFeatureRepository featureRepository;
-    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
 
     // -- constructors
     public static ApplicationFeatureViewModel newViewModel(
@@ -313,9 +313,9 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
     }
 
     // -- FACTORY
-    
+
     public static <T extends ApplicationFeatureViewModel> Function<ApplicationFeatureId, T> factory(
-            final @NonNull ApplicationFeatureRepository featureRepository, 
+            final @NonNull ApplicationFeatureRepository featureRepository,
             final @NonNull FactoryService factory,
             final @NonNull Class<T> viewmodelType) {
 
@@ -324,9 +324,9 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
     }
 
     // -- HELPER
-    
+
     protected <T extends ApplicationFeatureViewModel> List<T> asViewModels(
-            final java.util.Collection<ApplicationFeatureId> featureIds, 
+            final java.util.Collection<ApplicationFeatureId> featureIds,
             final Class<T> viewmodelType) {
         return featureIds.stream()
                 .map(factory(featureRepository, factory, viewmodelType))
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager.java
index 7af6069..144659a 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager.java
@@ -33,20 +33,20 @@ import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRep
         )
 public class ApplicationOrphanedPermissionManager {
 
-    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
-    
+    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+
     public String title() {
         return "Manage Orphaned Permissions";
     }
-    
+
     @org.apache.isis.applib.annotation.Collection(typeOf = ApplicationPermission.class)
     public Collection<? extends ApplicationPermission> getOrphanedPermissions() {
         return applicationPermissionRepository.findOrphaned();
     }
-    
+
 //    @Action
 //    public Collection<? extends ApplicationPermission> debugOrphanedPermissions() {
 //        return applicationPermissionRepository.findOrphaned();
 //    }
-    
+
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java
index c05f254..61c1cf1 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java
@@ -49,7 +49,7 @@ public class ApplicationPermissionMenu {
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermissionMenu, T> {}
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermissionMenu> {}
 
-    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
     @Inject private FactoryService factoryService;
 
     // -- iconName
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 20653a3..950adf4 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
@@ -45,7 +45,7 @@ public class ApplicationPermission_updateRole {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermission_updateRole> {}
 
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
 
     private final ApplicationPermission target;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRoleMenu.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRoleMenu.java
index 8360006..fb21f2a 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRoleMenu.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRoleMenu.java
@@ -54,7 +54,7 @@ public class ApplicationRoleMenu {
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationRoleMenu, T> {}
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRoleMenu> {}
 
-    private final ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    private final ApplicationRoleRepository applicationRoleRepository;
 
 
     // -- iconName
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 51cee50..4dbfd48 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
@@ -56,7 +56,7 @@ public class ApplicationRole_addPermission {
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_addPermission> {}
 
     @Inject private ApplicationFeatureRepository featureRepository;
-    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
 
     private final ApplicationRole target;
 
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 608fa07..eed1f0d 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
@@ -35,6 +35,7 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
+import lombok.val;
 
 @Action(
         domainEvent = ApplicationRole_addUser.ActionDomainEvent.class,
@@ -45,8 +46,8 @@ 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;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
 
     private final ApplicationRole target;
 
@@ -58,8 +59,8 @@ public class ApplicationRole_addUser {
 
     @MemberSupport
     public List<? extends ApplicationUser> autoComplete0Act(final String search) {
-        final Collection<? extends ApplicationUser> matchingSearch = applicationUserRepository.find(search);
-        final List<? extends ApplicationUser> list = _Lists.newArrayList(matchingSearch);
+        val matchingSearch = applicationUserRepository.find(search);
+        val list = _Lists.newArrayList(matchingSearch);
         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 57933e8..c97edfa 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
@@ -43,7 +43,7 @@ public class ApplicationRole_delete {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationRole_delete> {}
 
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
 
     private final ApplicationRole 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 f60f353..c741529 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
@@ -54,7 +54,7 @@ public class ApplicationRole_removePermissions {
     @Inject private MessageService messageService;
     @Inject private SecmanConfiguration configBean;
     @Inject private RepositoryService repository;
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
 
     private final ApplicationRole target;
 
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 4045256..e5ea89b 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
@@ -46,8 +46,8 @@ 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;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
 
     private final ApplicationRole target;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancyMenu.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancyMenu.java
index 0d41d54..e7f6e9c 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancyMenu.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancyMenu.java
@@ -52,7 +52,7 @@ public class ApplicationTenancyMenu {
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationTenancyMenu, T> {}
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationTenancyMenu> {}
 
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
 
     // -- iconName
     public String iconName() {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addChild.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addChild.java
index 7ff2af6..aac77fb 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addChild.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addChild.java
@@ -30,14 +30,14 @@ import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepositor
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = AddChildDomainEvent.class, 
+        domainEvent = AddChildDomainEvent.class,
         associateWith = "children")
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationTenancy_addChild {
-    
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
-    
+
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
+
     private final ApplicationTenancy target;
 
     @MemberSupport
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addUser.java
index bb5fa7a..e844c65 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_addUser.java
@@ -36,15 +36,15 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = AddUserDomainEvent.class, 
+        domainEvent = AddUserDomainEvent.class,
         associateWith = "users")
 @ActionLayout(named="Add", sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationTenancy_addUser {
-    
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
+
     private final ApplicationTenancy target;
 
     @MemberSupport
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_delete.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_delete.java
index a9486e7..57e3e2b 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_delete.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_delete.java
@@ -38,23 +38,23 @@ import org.apache.isis.extensions.secman.model.dom.user.ApplicationUser_updateAt
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-@Action(domainEvent = 
-        DeleteDomainEvent.class, 
+@Action(domainEvent =
+        DeleteDomainEvent.class,
         semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationTenancy_delete {
-    
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private FactoryService factoryService;
     @Inject private RepositoryService repository;
 
     private final ApplicationTenancy target;
 
-    
+
     @MemberSupport
-    public Collection<? extends ApplicationTenancy> act() {
+    public Collection<ApplicationTenancy> act() {
         for (val user : applicationUserRepository.findByTenancy(target)) {
             val updateAtPathMixin = factoryService.mixin(ApplicationUser_updateAtPath.class, user);
             updateAtPathMixin.act(null);
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeChild.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeChild.java
index 827b33f..2bb3bd1 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeChild.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeChild.java
@@ -32,13 +32,13 @@ import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepositor
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = RemoveChildDomainEvent.class, 
+        domainEvent = RemoveChildDomainEvent.class,
         associateWith = "children")
 @ActionLayout(sequence = "2")
 @RequiredArgsConstructor
 public class ApplicationTenancy_removeChild {
-    
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
+
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
 
     private final ApplicationTenancy target;
 
@@ -47,12 +47,12 @@ public class ApplicationTenancy_removeChild {
         applicationTenancyRepository.clearParentOnTenancy(child);
         return target;
     }
-    
+
     @MemberSupport
-    public Collection<? extends ApplicationTenancy> choices0Act() {
+    public Collection<ApplicationTenancy> choices0Act() {
         return applicationTenancyRepository.getChildren(target);
     }
-    
+
     @MemberSupport
     public String disableAct() {
         return choices0Act().isEmpty()? "No children to remove": null;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeUser.java
index 22f2b3e..1aee237 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_removeUser.java
@@ -34,28 +34,28 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = RemoveUserDomainEvent.class, 
+        domainEvent = RemoveUserDomainEvent.class,
         associateWith = "users")
 @ActionLayout(named="Remove", sequence = "2")
 @RequiredArgsConstructor
 public class ApplicationTenancy_removeUser {
-    
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
+
     private final ApplicationTenancy target;
-    
+
     @MemberSupport
     public ApplicationTenancy act(final ApplicationUser applicationUser) {
         applicationTenancyRepository.clearTenancyOnUser(applicationUser);
         return target;
     }
-    
+
     @MemberSupport
-    public Collection<? extends ApplicationUser> choices0Act() {
+    public Collection<ApplicationUser> choices0Act() {
         return applicationUserRepository.findByTenancy(target);
     }
-    
+
     @MemberSupport
     public String disableAct() {
         return choices0Act().isEmpty()? "No users to remove": null;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateParent.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateParent.java
index 959282f..f5bb12e 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateParent.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateParent.java
@@ -32,21 +32,21 @@ import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepositor
 import lombok.RequiredArgsConstructor;
 
 @Action(
-        domainEvent = UpdateParentDomainEvent.class, 
+        domainEvent = UpdateParentDomainEvent.class,
         associateWith = "parent")
 @ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class ApplicationTenancy_updateParent {
-    
-    @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
-    
+
+    @Inject private ApplicationTenancyRepository applicationTenancyRepository;
+
     private final ApplicationTenancy target;
 
     @MemberSupport
     public ApplicationTenancy act(
             @Parameter(optionality = Optionality.OPTIONAL)
             final ApplicationTenancy parent) {
-        
+
         applicationTenancyRepository.setParentOnTenancy(target, parent);
         return target;
     }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_users.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_users.java
index f6ee381..bb66e43 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_users.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_users.java
@@ -36,16 +36,16 @@ import lombok.RequiredArgsConstructor;
         )
 @RequiredArgsConstructor
 public class ApplicationTenancy_users {
-    
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
+    @Inject private ApplicationUserRepository applicationUserRepository;
+
     private final ApplicationTenancy target;
 
     // -- users (collection)
 
     public static class UsersDomainEvent extends CollectionDomainEvent<ApplicationUser> {}
 
-    public java.util.Collection<? extends ApplicationUser> coll() {
+    public java.util.Collection<ApplicationUser> coll() {
         return applicationUserRepository.findByAtPath(target.getPath());
     }
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java
index b2fdeb9..4825f90 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java
@@ -27,16 +27,8 @@ import org.apache.isis.applib.annotation.Nature;
         )
 public class ApplicationUserManager {
 
-//    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-
     public String title() {
-        return "Application User Manager"; 
+        return "Application User Manager";
     }
 
-//XXX provided via mixins, that is one specific to JPA the other specific to JDO    
-//    @Collection
-//    public java.util.Collection<? extends ApplicationUser> getAllUsers() {
-//        return applicationUserRepository.allUsers();
-//    }
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_allUsers.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_allUsers.java
index 671cbda..f279a97 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_allUsers.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_allUsers.java
@@ -27,20 +27,20 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 /**
  * @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_allUsers<U extends ApplicationUser> {
-    
-    @Inject private ApplicationUserRepository<U> applicationUserRepository;
-    
-    protected Collection<U> doColl() {
-        return applicationUserRepository.allUsers();        
+public abstract class ApplicationUserManager_allUsers {
+
+    @Inject private ApplicationUserRepository applicationUserRepository;
+
+    protected Collection<ApplicationUser> doColl() {
+        return applicationUserRepository.allUsers();
     }
 
 
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 f5991ad..b48df99 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
@@ -43,20 +43,20 @@ import lombok.val;
  * overridden with the concrete subclasses.
  *
  */
-public abstract class ApplicationUserManager_newDelegateUser<R extends ApplicationRole> {
+public abstract class ApplicationUserManager_newDelegateUser {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUserManager_newDelegateUser> {}
 
     @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
-    @Inject private ApplicationRoleRepository<R> applicationRoleRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
     @Inject private RepositoryService repository;
     @Inject private SecurityRealmService securityRealmService;
 
     protected ApplicationUser doAct(
           final String username,
-          final R initialRole,
+          final ApplicationRole initialRole,
           final Boolean enabled) {
 
         final ApplicationUser user = applicationUserRepository
@@ -73,7 +73,7 @@ public abstract class ApplicationUserManager_newDelegateUser<R extends Applicati
         return hasNoDelegateAuthenticationRealm();
     }
 
-    protected R doDefault1() {
+    protected ApplicationRole doDefault1() {
         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/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
index 05281b0..917b507 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
@@ -43,12 +43,12 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
  * overridden with the concrete subclasses.
  *
  */
-public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationRole> {
+public abstract class ApplicationUserManager_newLocalUser {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUserManager_newLocalUser> {}
 
-    @Inject private ApplicationRoleRepository<R> applicationRoleRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
     @Inject private FactoryService factory;
     @Inject private RepositoryService repository;
@@ -57,7 +57,7 @@ public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationR
             final String username,
             final Password password,
             final Password passwordRepeat,
-            final R initialRole,
+            final ApplicationRole initialRole,
             final Boolean enabled,
             final String emailAddress) {
 
@@ -81,7 +81,7 @@ public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationR
             final String username,
             final Password newPassword,
             final Password newPasswordRepeat,
-            final R initialRole,
+            final ApplicationRole initialRole,
             final Boolean enabled,
             final String emailAddress) {
 
@@ -92,7 +92,7 @@ public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationR
         return null;
     }
 
-    protected R doDefault3() {
+    protected ApplicationRole 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/ApplicationUserMenu.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java
index 902eb4d..5d25fa7 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java
@@ -46,13 +46,10 @@ import lombok.val;
         )
 public class ApplicationUserMenu {
 
-    //@Inject private SecmanConfiguration configBean;
-    //@Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    //@Inject private SecurityRealmService securityRealmService;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private FactoryService factory;
 
-    public static abstract class PropertyDomainEvent<T> 
+    public static abstract class PropertyDomainEvent<T>
     extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationUserMenu, T> {
     }
 
@@ -60,7 +57,7 @@ public class ApplicationUserMenu {
     extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationUserMenu, T> {
     }
 
-    public static abstract class ActionDomainEvent 
+    public static abstract class ActionDomainEvent
     extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUserMenu> {
     }
 
@@ -81,10 +78,10 @@ public class ApplicationUserMenu {
             final @ParameterLayout(named = "Search") String search) {
         return applicationUserRepository.find(search);
     }
-    
+
     public static class ApplicationUserManagerDomainEvent extends ActionDomainEvent {
     }
-    
+
     @Action(
             domainEvent = ApplicationUserManagerDomainEvent.class,
             semantics = SemanticsOf.IDEMPOTENT
@@ -115,7 +112,7 @@ public class ApplicationUserMenu {
 //            @Parameter(optionality = Optionality.OPTIONAL)
 //            @ParameterLayout(named = "Enabled?")
 //            final Boolean enabled) {
-//        
+//
 //        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
 //        val newDelegateUserMixin = factory.mixin(
 //                ApplicationUserManager_newDelegateUser.class, applicationUserManager);
@@ -157,7 +154,7 @@ public class ApplicationUserMenu {
 //            @Parameter(optionality = Optionality.OPTIONAL)
 //            @ParameterLayout(named = "Email Address")
 //            final String emailAddress) {
-//        
+//
 //        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
 //        val newLocalUserMixin = factory.mixin(
 //                ApplicationUserManager_newLocalUser.class, applicationUserManager);
@@ -171,11 +168,11 @@ public class ApplicationUserMenu {
 //            final ApplicationRole initialRole,
 //            final Boolean enabled,
 //            final String emailAddress) {
-//        
+//
 //        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
 //        val newLocalUserMixin = factory.mixin(
 //                ApplicationUserManager_newLocalUser.class, applicationUserManager);
-//        
+//
 //        return newLocalUserMixin.doValidate(
 //                username, password, passwordRepeat, initialRole, enabled, emailAddress);
 //    }
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 d5ff1dc..313dce5 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
@@ -19,6 +19,7 @@
 package org.apache.isis.extensions.secman.model.dom.user;
 
 import java.util.Collection;
+import java.util.TreeSet;
 
 import javax.inject.Inject;
 
@@ -43,7 +44,7 @@ public class ApplicationUser_addRole {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_addRole> {}
 
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
 
     private final ApplicationUser target;
 
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 0954621..0908ba7 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
@@ -44,7 +44,7 @@ public class ApplicationUser_delete {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_delete> {}
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private RepositoryService repository;
 
     private final ApplicationUser target;
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 2cd40c9..7b26972 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
@@ -45,8 +45,8 @@ 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;
+    @Inject private ApplicationUserRepository applicationUserRepository;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
 
     private final ApplicationUser target;
 
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 3ecd459..55d34b3 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
@@ -41,7 +41,7 @@ public class ApplicationUser_lock {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_lock> {}
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
 
     private final ApplicationUser 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 dd13f3f..5194171 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
@@ -46,8 +46,8 @@ 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;
+    @Inject private ApplicationRoleRepository applicationRoleRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
 
     private final ApplicationUser target;
 
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 728ec1b..41a9600 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
@@ -43,7 +43,7 @@ public class ApplicationUser_resetPassword {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_resetPassword> {}
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
 
     private final ApplicationUser target;
 
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 233b104..1ae020f 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
@@ -40,7 +40,7 @@ public class ApplicationUser_updateAccountType {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updateAccountType> {}
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
 
     private final ApplicationUser target;
 
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 0ab1835..6579671 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
@@ -47,7 +47,7 @@ public class ApplicationUser_updatePassword {
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationUser_updatePassword> {}
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private Optional<PasswordEncryptionService> passwordEncryptionService; // empty if no candidate is available
 
     private final ApplicationUser target;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java
index 60f98ad..904c034 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java
@@ -36,11 +36,11 @@ import lombok.RequiredArgsConstructor;
         domainEvent = HasUsername_open.ActionDomainEvent.class,
         associateWith = "User" // associate with a 'User' property (if any)
         )
-@ActionLayout(sequence = "1") 
+@ActionLayout(sequence = "1")
 @RequiredArgsConstructor
 public class HasUsername_open {
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
 
     private final HasUsername target;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/MeService.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/MeService.java
index 14d2504..22aee8d 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/MeService.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/MeService.java
@@ -50,7 +50,7 @@ public class MeService {
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<MeService, T> {}
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<MeService> {}
 
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private UserService userService;
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
@@ -69,10 +69,10 @@ public class MeService {
     @ActionLayout(
             cssClassFa = "fa-user",
             describedAs = "Looks up ApplicationUser entity corresponding to your user account",
-            //group = "Security", 
-            sequence = "100" 
+            //group = "Security",
+            sequence = "100"
             )
-    
+
     public ApplicationUser me() {
         return queryResultsCacheProvider.get().execute(new Callable<ApplicationUser>() {
             @Override
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/UserPermissionViewModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/UserPermissionViewModel.java
index 94fe192..6c9f03a 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/UserPermissionViewModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/UserPermissionViewModel.java
@@ -76,23 +76,23 @@ public class UserPermissionViewModel implements ViewModel {
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<UserPermissionViewModel> {}
 
     private static final int TYPICAL_LENGTH_VERB = 12;
-    
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+
+    @Inject private ApplicationUserRepository applicationUserRepository;
     @Inject private FactoryService factory;
     @Inject private ApplicationFeatureRepository featureRepository;
-    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
 
     // -- constructors, factory methods
     public static UserPermissionViewModel newViewModel(
-            final ApplicationFeatureId featureId, 
-            final ApplicationUser user, 
-            final ApplicationPermissionValueSet.Evaluation viewingEvaluation, 
-            final ApplicationPermissionValueSet.Evaluation changingEvaluation, 
+            final ApplicationFeatureId featureId,
+            final ApplicationUser user,
+            final ApplicationPermissionValueSet.Evaluation viewingEvaluation,
+            final ApplicationPermissionValueSet.Evaluation changingEvaluation,
             final FactoryService factory) {
 
         return factory
                 .viewModel(
-                        UserPermissionViewModel.class, 
+                        UserPermissionViewModel.class,
                         asEncodedString(featureId, user.getUsername(), viewingEvaluation, changingEvaluation));
     }
 
@@ -144,21 +144,21 @@ public class UserPermissionViewModel implements ViewModel {
         final ApplicationFeatureId changingEvaluationCauseFeatureId = changingEvaluationCause != null? changingEvaluationCause.getFeatureId(): null;
 
         return join(
-        username, 
-        
+        username,
+
         viewingEvaluationGranted,
         viewingEvaluationCauseFeatureId != null? viewingEvaluationCauseFeatureId.getSort(): "",
         viewingEvaluationCauseFeatureId != null? viewingEvaluationCauseFeatureId.getFullyQualifiedName(): "",
         viewingEvaluationCause != null? viewingEvaluationCause.getRule(): "",
         viewingEvaluationCause != null? viewingEvaluationCause.getMode(): "",
-        
+
         changingEvaluationGranted,
         changingEvaluationCauseFeatureId != null? changingEvaluationCauseFeatureId.getSort(): "",
         changingEvaluationCauseFeatureId != null? changingEvaluationCauseFeatureId.getFullyQualifiedName(): "",
         changingEvaluationCause != null? changingEvaluationCause.getRule(): "",
         changingEvaluationCause != null? changingEvaluationCause.getMode(): "",
-        
-        featureId.getSort(), 
+
+        featureId.getSort(),
         featureId.getFullyQualifiedName()
         );
     }
@@ -185,7 +185,7 @@ public class UserPermissionViewModel implements ViewModel {
         final ApplicationFeatureSort viewingEvaluationFeatureIdType =  !viewingEvaluationCauseFeatureIdType.isEmpty() ? ApplicationFeatureSort.valueOf(viewingEvaluationCauseFeatureIdType) : null;
         final String viewingEvaluationFeatureFqn = iterator.next();
         this.viewingFeatureId = viewingEvaluationFeatureIdType != null
-                ? ApplicationFeatureId.newFeature(viewingEvaluationFeatureIdType, viewingEvaluationFeatureFqn) 
+                ? ApplicationFeatureId.newFeature(viewingEvaluationFeatureIdType, viewingEvaluationFeatureFqn)
                 : null;
 
         final String viewingEvaluationCauseRule = iterator.next();
@@ -199,7 +199,7 @@ public class UserPermissionViewModel implements ViewModel {
         final ApplicationFeatureSort changingEvaluationFeatureIdType =  !changingEvaluationCauseFeatureIdType.isEmpty() ? ApplicationFeatureSort.valueOf(changingEvaluationCauseFeatureIdType) : null;
         final String changingEvaluationFeatureFqn = iterator.next();
         this.changingFeatureId = changingEvaluationFeatureIdType != null
-                ? ApplicationFeatureId.newFeature(changingEvaluationFeatureIdType, changingEvaluationFeatureFqn) 
+                ? ApplicationFeatureId.newFeature(changingEvaluationFeatureIdType, changingEvaluationFeatureFqn)
                 : null;
 
         final String changingEvaluationCauseRule = iterator.next();
@@ -371,7 +371,7 @@ public class UserPermissionViewModel implements ViewModel {
 
     // -- toString
 
-    private static final ToString<UserPermissionViewModel> toString = 
+    private static final ToString<UserPermissionViewModel> toString =
             ObjectContracts
             .toString("user", UserPermissionViewModel::getUser)
             .thenToString("featureId", UserPermissionViewModel::getFeatureId);
@@ -384,7 +384,7 @@ public class UserPermissionViewModel implements ViewModel {
     // -- Factory
 
     public static Function<ApplicationFeature, UserPermissionViewModel> asViewModel(
-            final ApplicationUser user, 
+            final ApplicationUser user,
             final FactoryService factoryService) {
 
         return (final ApplicationFeature feature) -> {
@@ -393,10 +393,10 @@ public class UserPermissionViewModel implements ViewModel {
             val viewingEvaluation = permissionSet.evaluate(feature.getFeatureId(), ApplicationPermissionMode.VIEWING);
             return UserPermissionViewModel
                     .newViewModel(
-                            feature.getFeatureId(), 
-                            user, 
-                            viewingEvaluation, 
-                            changingEvaluation, 
+                            feature.getFeatureId(),
+                            user,
+                            viewingEvaluation,
+                            changingEvaluation,
                             factoryService);
         };
     }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java
index a760824..f5533e2 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java
@@ -41,13 +41,13 @@ public class TenantedAuthorizationFacetDefault extends FacetAbstract implements
     }
 
     private final List<ApplicationTenancyEvaluator> evaluators;
-    private final ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    private final ApplicationUserRepository applicationUserRepository;
     private final Provider<QueryResultsCache> queryResultsCacheProvider;
     private final UserService userService;
 
     public TenantedAuthorizationFacetDefault(
             final List<ApplicationTenancyEvaluator> evaluators,
-            final ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository,
+            final ApplicationUserRepository applicationUserRepository,
             final Provider<QueryResultsCache> queryResultsCacheProvider,
             final UserService userService,
             final FacetHolder holder) {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationPostProcessor.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationPostProcessor.java
index f3efdae..5aafdc4 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationPostProcessor.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationPostProcessor.java
@@ -110,7 +110,7 @@ public class TenantedAuthorizationPostProcessor
     @Inject ServiceRegistry serviceRegistry;
     @Inject ServiceInjector serviceInjector;
     @Inject UserService userService;
-    @Inject @Lazy ApplicationUserRepository<? extends ApplicationUser> userRepository;
+    @Inject @Lazy ApplicationUserRepository userRepository;
     @Inject Provider<QueryResultsCache> queryResultsCacheProvider;
 
 }
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 55f61a3..eea3492 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
@@ -32,8 +32,8 @@ import lombok.val;
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 public class ImpersonateMenuAdvisorForSecman implements ImpersonateMenuAdvisor {
 
-    final ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    final ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    final ApplicationUserRepository applicationUserRepository;
+    final ApplicationRoleRepository applicationRoleRepository;
 
     final UserService userService;
     final MessageService messageService;
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermission.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermission.java
index 26a13bd..922e5e3 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermission.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermission.java
@@ -44,7 +44,6 @@ import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMod
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValue;
 import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
-import org.apache.isis.extensions.secman.jdo.dom.user.ApplicationUser;
 
 import lombok.Getter;
 import lombok.Setter;
@@ -107,9 +106,7 @@ import lombok.experimental.UtilityClass;
         bookmarking = BookmarkPolicy.AS_CHILD
 )
 public class ApplicationPermission
-implements
-    org.apache.isis.extensions.secman.api.permission.ApplicationPermission<ApplicationUser, ApplicationRole>,
-    Comparable<ApplicationPermission> {
+implements org.apache.isis.extensions.secman.api.permission.ApplicationPermission  {
 
     @Inject ApplicationFeatureRepository featureRepository;
 
@@ -117,16 +114,24 @@ implements
     // -- ROLE
 
     @Role
-    @Getter(onMethod = @__(@Override))
-    @Setter(onMethod = @__(@Override))
     @javax.jdo.annotations.Column(name = "roleId", allowsNull="false")
+    @Getter(onMethod = @__(@Override))
     private ApplicationRole role;
 
+    public void setRole(ApplicationRole role) {
+        this.role = role;
+    }
+
+    @Override
+    public void setRole(org.apache.isis.extensions.secman.api.role.ApplicationRole applicationRole) {
+        setRole((ApplicationRole) applicationRole);
+    }
+
 
     // -- FEATURE FQN
 
     @FeatureFqn
-    @javax.jdo.annotations.Column(allowsNull="false")
+    @javax.jdo.annotations.Column(allowsNull="false", length = FeatureFqn.MAX_LENGTH)
     @Getter(onMethod = @__(@Override))
     @Setter(onMethod = @__(@Override))
     private String featureFqn;
@@ -192,8 +197,8 @@ implements
             .thenUse("mode", ApplicationPermission::getMode);
 
     @Override
-    public int compareTo(final ApplicationPermission other) {
-        return contract.compare(this, other);
+    public int compareTo(final org.apache.isis.extensions.secman.api.permission.ApplicationPermission other) {
+        return contract.compare(this, (ApplicationPermission) other);
     }
 
     @Override
@@ -216,7 +221,7 @@ implements
     public static class DefaultComparator implements Comparator<ApplicationPermission> {
         @Override
         public int compare(final ApplicationPermission o1, final ApplicationPermission o2) {
-            return Objects.compare(o1, o2, (a, b) -> a.compareTo(b) );
+            return Objects.compare(o1, o2, ApplicationPermission::compareTo);
         }
     }
 
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java
index 400483e..be4c1fc 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java
@@ -54,13 +54,13 @@ import lombok.val;
 @Repository
 @Named("isis.ext.secman.ApplicationPermissionRepository")
 public class ApplicationPermissionRepository
-implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository<ApplicationPermission> {
+implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository {
 
     @Inject private RepositoryService repository;
     @Inject private ApplicationFeatureRepository featureRepository;
     @Inject private FactoryService factory;
     @Inject private MessageService messages;
-    
+
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
     @Override
@@ -83,7 +83,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
     // -- findByUser (programmatic)
     public List<ApplicationPermission> findByUserCached(@NonNull final ApplicationUser user) {
-        return queryResultsCacheProvider.get().execute(this::findByUser, 
+        return queryResultsCacheProvider.get().execute(this::findByUser,
                 ApplicationPermissionRepository.class, "findByUserCached", user);
     }
 
@@ -102,16 +102,17 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     /**
      * Uses the {@link QueryResultsCache} in order to support
      * multiple lookups from <code>org.apache.isis.extensions.secman.jdo.app.user.UserPermissionViewModel</code>.
+     * @return
      */
     @Override
-    public Optional<ApplicationPermission> findByUserAndPermissionValue(final String username, final ApplicationPermissionValue permissionValue) {
+    public Optional<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> findByUserAndPermissionValue(final String username, final ApplicationPermissionValue permissionValue) {
 
         // obtain all permissions for this user, map by its value, and
         // put into query cache (so that this method can be safely called in a tight loop)
         val permissions =
                 queryResultsCacheProvider.get().execute(
-                        this::permissionsByPermissionValue, 
-                        ApplicationPermissionRepository.class, "findByUserAndPermissionValue", 
+                        this::permissionsByPermissionValue,
+                        ApplicationPermissionRepository.class, "findByUserAndPermissionValue",
                         username);
 
         // now simply return the permission from the required value (if it exists)
@@ -120,16 +121,16 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
                 ? Optional.of(applicationPermissions.get(0))
                         : Optional.empty();
     }
-    
+
     private ListMultimap<ApplicationPermissionValue, ApplicationPermission> permissionsByPermissionValue(
             final String username) {
 
         // only username (and not permissionValue) is the key
         // (we are obtaining all the perms for this user)
-        
+
         val permissionsByPermissionValue =
                 _Multimaps.<ApplicationPermissionValue, ApplicationPermission>newListMultimap();
-        
+
         val permissions = findByUser(username);
 
         _NullSafe.stream(permissions)
@@ -143,17 +144,19 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
     // -- findByRoleAndRuleAndFeatureType (programmatic)
     @Override
-    public Collection<ApplicationPermission> findByRoleAndRuleAndFeatureTypeCached(
+    public Collection<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> findByRoleAndRuleAndFeatureTypeCached(
             org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             ApplicationPermissionRule rule,
             ApplicationFeatureSort type) {
-        return queryResultsCacheProvider.get().execute(this::findByRoleAndRuleAndFeatureType, 
-                ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureTypeCached", 
-                role, rule, type);
+        //noinspection unchecked
+        return (Collection)queryResultsCacheProvider.get().execute(this::findByRoleAndRuleAndFeatureType,
+                ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureTypeCached",
+                role, rule, type)
+                ;
     }
 
     public Collection<ApplicationPermission> findByRoleAndRuleAndFeatureType(
-            org.apache.isis.extensions.secman.api.role.ApplicationRole role, 
+            org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             final ApplicationPermissionRule rule,
             final ApplicationFeatureSort type) {
         return repository.allMatches(Query.named(
@@ -167,7 +170,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
 
     // -- findByRoleAndRuleAndFeature (programmatic)
-    public Optional<ApplicationPermission> findByRoleAndRuleAndFeatureCached(
+    public Optional<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> findByRoleAndRuleAndFeatureCached(
             final org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             final ApplicationPermissionRule rule,
             final ApplicationFeatureSort featureSort,
@@ -179,7 +182,17 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     }
 
     @Override
-    public Optional<ApplicationPermission> findByRoleAndRuleAndFeature(
+    public Optional<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> findByRoleAndRuleAndFeature(
+            final org.apache.isis.extensions.secman.api.role.ApplicationRole role,
+            final ApplicationPermissionRule rule,
+            final ApplicationFeatureSort featureSort,
+            final String featureFqn) {
+
+        return findByRoleAndRuleAndFeature_(role, rule, featureSort, featureFqn)
+                .map(org.apache.isis.extensions.secman.api.permission.ApplicationPermission.class::cast);
+    }
+
+    private Optional<ApplicationPermission> findByRoleAndRuleAndFeature_(
             final org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             final ApplicationPermissionRule rule,
             final ApplicationFeatureSort featureSort,
@@ -198,13 +211,18 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     // -- findByFeature (programmatic)
 
     @Override
-    public Collection<ApplicationPermission> findByFeatureCached(final ApplicationFeatureId featureId) {
+    public Collection<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> findByFeatureCached(final ApplicationFeatureId featureId) {
+        //noinspection unchecked
+        return (Collection)findByFeatureCached_(featureId);
+    }
+
+    private Collection<ApplicationPermission> findByFeatureCached_(final ApplicationFeatureId featureId) {
         return queryResultsCacheProvider.get().execute(
-                this::findByFeature, ApplicationPermissionRepository.class, "findByFeatureCached",
+                this::findByFeature, ApplicationPermissionRepository.class, "findByFeatureCached_",
                 featureId);
     }
 
-    public Collection<ApplicationPermission> findByFeature(final ApplicationFeatureId featureId) {
+    private Collection<ApplicationPermission> findByFeature(final ApplicationFeatureId featureId) {
         return repository.allMatches(
                 Query.named(
                         ApplicationPermission.class, "findByFeature")
@@ -243,6 +261,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final String featureFqn) {
 
         ApplicationPermission permission = findByRoleAndRuleAndFeature(role, rule, featureSort, featureFqn)
+                .map(ApplicationPermission.class::cast)
                 .orElse(null);
         if (permission != null) {
             return permission;
@@ -273,8 +292,8 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     @Override
     public ApplicationPermission newPermission(
             final org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole,
-            final ApplicationPermissionRule rule, 
-            final ApplicationPermissionMode mode, 
+            final ApplicationPermissionRule rule,
+            final ApplicationPermissionMode mode,
             final ApplicationFeatureId featureId) {
 
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
@@ -297,11 +316,16 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
         return permission;
     }
-    
+
 
     // -- allPermission (programmatic)
     @Override
-    public Collection<ApplicationPermission> allPermissions() {
+    public Collection<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> allPermissions() {
+        //noinspection unchecked
+        return (Collection)allPermissions_();
+    }
+
+    private Collection<ApplicationPermission> allPermissions_() {
         return repository.allInstances(ApplicationPermission.class)
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
@@ -310,21 +334,25 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     // -- findOrphaned (programmatic)
 
     @Override
-    public Collection<ApplicationPermission> findOrphaned() {
+    public Collection<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> findOrphaned() {
+        return (Collection)findOrphaned_();
+    }
+
+    private Collection<ApplicationPermission> findOrphaned_() {
 
-        val featureNamesKnownToTheMetamodel =  
+        val featureNamesKnownToTheMetamodel =
                 featureRepository.getFeatureIdentifiersByName().keySet();
 
         val orphaned = _Lists.<ApplicationPermission>newArrayList();
 
-        for (val permission : allPermissions()) {
-            
+        for (val permission : allPermissions_()) {
+
             val featId = permission.asFeatureId().orElse(null);
             if(featId==null) {
                 orphaned.add(permission);
                 continue;
             }
-            
+
             if(!featureNamesKnownToTheMetamodel.contains(featId.getFullyQualifiedName())) {
                 orphaned.add(permission);
             }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRole.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRole.java
index c390b30..d0b2bee 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRole.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRole.java
@@ -84,7 +84,7 @@ import lombok.Setter;
         bookmarking = BookmarkPolicy.AS_ROOT
         )
 public class ApplicationRole
-implements org.apache.isis.extensions.secman.api.role.ApplicationRole<ApplicationUser,ApplicationRole>, Comparable<ApplicationRole> {
+implements org.apache.isis.extensions.secman.api.role.ApplicationRole {
 
     @Inject private ApplicationPermissionRepository applicationPermissionRepository;
 
@@ -173,8 +173,8 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRole<Applicatio
 
 
     @Override
-    public int compareTo(final ApplicationRole o) {
-        return comparator.compare(this, o);
+    public int compareTo(final org.apache.isis.extensions.secman.api.role.ApplicationRole o) {
+        return comparator.compare(this, (ApplicationRole) o);
     }
 
     @Override
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRoleRepository.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRoleRepository.java
index ff5178e..8c6f816 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRoleRepository.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/role/ApplicationRoleRepository.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -43,7 +44,7 @@ import lombok.val;
 @Repository
 @Named("isis.ext.secman.ApplicationRoleRepository")
 public class ApplicationRoleRepository
-implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<ApplicationRole> {
+implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository {
 
     @Inject private FactoryService factoryService;
     @Inject private RepositoryService repository;
@@ -58,28 +59,31 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
     }
 
     @Override
-    public Optional<ApplicationRole> findByNameCached(final String name) {
+    public Optional<org.apache.isis.extensions.secman.api.role.ApplicationRole> findByNameCached(final String name) {
         return queryResultsCacheProvider.get().execute(()->findByName(name),
-                ApplicationRoleRepository.class, "findByNameCached", name);
+                ApplicationRoleRepository.class, "findByNameCached", name)
+                .map(org.apache.isis.extensions.secman.api.role.ApplicationRole.class::cast);
     }
 
     @Override
     public ApplicationRole upsert(final String name, final String roleDescription) {
         return findByName(name)
+                .map(ApplicationRole.class::cast)
                 .orElseGet(() -> newRole(name, roleDescription));
     }
 
     @Override
-    public Optional<ApplicationRole> findByName(final String name) {
+    public Optional<org.apache.isis.extensions.secman.api.role.ApplicationRole> findByName(final String name) {
         if(name == null) {
             return Optional.empty();
         }
         return repository.uniqueMatch(Query.named(ApplicationRole.class, "findByName")
-                .withParameter("name", name));
+                .withParameter("name", name))
+                .map(org.apache.isis.extensions.secman.api.role.ApplicationRole.class::cast);
     }
 
     @Override
-    public Collection<ApplicationRole> findNameContaining(final String search) {
+    public Collection<org.apache.isis.extensions.secman.api.role.ApplicationRole> findNameContaining(final String search) {
 
         if(search != null && search.length() > 0) {
             String nameRegex = String.format("(?i).*%s.*", search.replace("*", ".*").replace("?", "."));
@@ -96,7 +100,9 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
     public ApplicationRole newRole(
             final String name,
             final String description) {
-        ApplicationRole role = findByName(name).orElse(null);
+        ApplicationRole role = findByName(name)
+                .map(ApplicationRole.class::cast)
+                .orElse(null);
         if (role == null){
             role = newApplicationRole();
             role.setName(name);
@@ -107,14 +113,14 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
     }
 
     @Override
-    public Collection<ApplicationRole> allRoles() {
+    public Collection<org.apache.isis.extensions.secman.api.role.ApplicationRole> allRoles() {
         return repository.allInstances(ApplicationRole.class)
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
     @Override
-    public Collection<ApplicationRole> findMatching(String search) {
+    public Collection<org.apache.isis.extensions.secman.api.role.ApplicationRole> findMatching(String search) {
         if (search != null && search.length() > 0 ) {
             return findNameContaining(search);
         }
@@ -145,7 +151,10 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
 
     @Override
     public boolean isAdminRole(org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) {
-        final ApplicationRole adminRole = findByNameCached(configBean.getAdminRoleName()).orElse(null);
+        final ApplicationRole adminRole =
+                findByNameCached(configBean.getAdminRoleName())
+                .map(ApplicationRole.class::cast)
+                .orElse(null);
         return Objects.equals(adminRole, genericRole);
     }
 
@@ -163,11 +172,5 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
         repository.removeAndFlush(role);
     }
 
-    @Override
-    public Collection<ApplicationRole> getRoles(
-            org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
-        val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
-        return user.getRoles();
-    }
 
 }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancy.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancy.java
index 70903ca..a820bba 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancy.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancy.java
@@ -83,7 +83,7 @@ import lombok.Setter;
 @DomainObjectLayout(
         bookmarking = BookmarkPolicy.AS_ROOT
         )
-public class ApplicationTenancy implements Comparable<ApplicationTenancy>,
+public class ApplicationTenancy implements
 org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy {
 
     // -- name (property, title)
@@ -191,8 +191,8 @@ org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy {
     }
 
     @Override
-    public int compareTo(final ApplicationTenancy o) {
-        return comparator.compare(this, o);
+    public int compareTo(final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy o) {
+        return comparator.compare(this, (ApplicationTenancy) o);
     }
 
 }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java
index d442b94..3fff78b 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/tenancy/ApplicationTenancyRepository.java
@@ -20,7 +20,7 @@ package org.apache.isis.extensions.secman.jdo.dom.tenancy;
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.concurrent.Callable;
+import java.util.SortedSet;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -32,6 +32,7 @@ import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.extensions.secman.jdo.dom.user.ApplicationUser;
 
@@ -41,11 +42,10 @@ import lombok.val;
 @Repository
 @Named("isis.ext.secman.ApplicationTenancyRepository")
 public class ApplicationTenancyRepository
-implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepository<ApplicationTenancy> {
+implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepository {
 
     @Inject private FactoryService factory;
     @Inject private RepositoryService repository;
-
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
     @Override
@@ -53,18 +53,22 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
         return factory.detachedEntity(new ApplicationTenancy());
     }
 
+
     // -- findByNameOrPathMatching
 
     @Override
-    public Collection<ApplicationTenancy> findByNameOrPathMatchingCached(final String search) {
-        return queryResultsCacheProvider.get().execute(new Callable<Collection<ApplicationTenancy>>() {
-            @Override public Collection<ApplicationTenancy> call() throws Exception {
-                return findByNameOrPathMatching(search);
-            }
-        }, ApplicationTenancyRepository.class, "findByNameOrPathMatchingCached", search);
+    public Collection<org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy> findByNameOrPathMatchingCached(final String search) {
+        return queryResultsCacheProvider.get().execute(
+                () -> findByNameOrPathMatching(search),
+                ApplicationTenancyRepository.class,
+                "findByNameOrPathMatchingCached", search);
+    }
+
+    private Collection<org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy> findByNameOrPathMatching(final String search) {
+        return _Casts.uncheckedCast(findByNameOrPathMatching_(search));
     }
 
-    public Collection<ApplicationTenancy> findByNameOrPathMatching(final String search) {
+    private SortedSet<ApplicationTenancy> findByNameOrPathMatching_(String search) {
         if (search == null) {
             return Collections.emptySortedSet();
         }
@@ -74,51 +78,50 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
+
     // -- findByName
 
     public ApplicationTenancy findByNameCached(final String name) {
-        return queryResultsCacheProvider.get().execute(new Callable<ApplicationTenancy>() {
-            @Override
-            public ApplicationTenancy call() throws Exception {
-                return findByName(name);
-            }
-        }, ApplicationTenancyRepository.class, "findByNameCached", name);
+        return queryResultsCacheProvider.get().execute(
+                () -> findByName(name),
+                ApplicationTenancyRepository.class,
+                "findByNameCached", name);
     }
 
     public ApplicationTenancy findByName(final String name) {
-        return repository.uniqueMatch(Query.named(ApplicationTenancy.class, "findByName")
-                .withParameter("name", name)).orElse(null);
+        return repository.uniqueMatch(
+                    Query.named(ApplicationTenancy.class, "findByName")
+                         .withParameter("name", name))
+                .orElse(null);
     }
 
 
     // -- findByPath
 
     public ApplicationTenancy findByPathCached(final String path) {
-        return queryResultsCacheProvider.get().execute(new Callable<ApplicationTenancy>() {
-            @Override
-            public ApplicationTenancy call() throws Exception {
-                return findByPath(path);
-            }
-        }, ApplicationTenancyRepository.class, "findByPathCached", path);
+        return queryResultsCacheProvider.get().execute(
+                () -> findByPath(path),
+                ApplicationTenancyRepository.class,
+                "findByPathCached", path);
     }
 
     public ApplicationTenancy findByPath(final String path) {
         if (path == null) {
             return null;
         }
-        return repository.uniqueMatch(Query.named(ApplicationTenancy.class, "findByPath")
-                .withParameter("path", path))
+        return repository.uniqueMatch(
+                    Query.named(ApplicationTenancy.class, "findByPath")
+                         .withParameter("path", path))
                 .orElse(null);
     }
 
 
     // -- autoComplete
     @Override
-    public Collection<ApplicationTenancy> findMatching(final String search) {
-        if (search != null && search.length() > 0) {
-            return findByNameOrPathMatching(search);
-        }
-        return Collections.emptySortedSet();
+    public Collection<org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy> findMatching(final String search) {
+        return _Strings.isNullOrEmpty(search)
+                ? Collections.emptySortedSet()
+                : findByNameOrPathMatching(search);
     }
 
     // -- newTenancy
@@ -148,19 +151,19 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
     // --
 
     @Override
-    public Collection<ApplicationTenancy> allTenancies() {
-        return queryResultsCacheProvider.get().execute(new Callable<Collection<ApplicationTenancy>>() {
-            @Override
-            public Collection<ApplicationTenancy> call() throws Exception {
-                return allTenanciesNoCache();
-            }
-        }, ApplicationTenancyRepository.class, "allTenancies");
+    public Collection<org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy> allTenancies() {
+        return queryResultsCacheProvider.get().execute(
+                this::allTenanciesNoCache,
+                ApplicationTenancyRepository.class, "allTenancies");
     }
 
-    public Collection<ApplicationTenancy> allTenanciesNoCache() {
+    public Collection<org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy> allTenanciesNoCache() {
+        return _Casts.uncheckedCast(allTenanciesNoCache_());
+    }
+
+    private SortedSet<ApplicationTenancy> allTenanciesNoCache_() {
         return repository.allInstances(ApplicationTenancy.class)
                 .stream()
-                .map(ApplicationTenancy.class::cast)
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
@@ -170,7 +173,6 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
             @NonNull final org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
         val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
         val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
-        // no need to add to users set, since will be done by JDO/DN.
         user.setAtPath(tenancy.getPath());
     }
 
@@ -178,7 +180,6 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
     public void clearTenancyOnUser(
             @NonNull final org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
         val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
-        // no need to remove from users set, since will be done by JDO/DN.
         user.setAtPath(null);
     }
 
@@ -208,8 +209,12 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
     }
 
     @Override
-    public Collection<ApplicationTenancy> getChildren(
+    public Collection<org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy> getChildren(
             @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
+        return _Casts.uncheckedCast(getChildren_(genericTenancy));
+    }
+
+    private SortedSet<ApplicationTenancy> getChildren_(org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
         val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
         return tenancy.getChildren()
                 .stream()
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 16d720f..50a5a65 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
@@ -111,7 +111,7 @@ import lombok.val;
         bookmarking = BookmarkPolicy.AS_ROOT
         )
 public class ApplicationUser
-        implements org.apache.isis.extensions.secman.api.user.ApplicationUser<ApplicationUser, ApplicationRole> {
+        implements org.apache.isis.extensions.secman.api.user.ApplicationUser {
 
     @Inject private ApplicationPermissionRepository applicationPermissionRepository;
     @Inject private UserService userService;
@@ -271,8 +271,8 @@ public class ApplicationUser
 
 
     @Override
-    public int compareTo(final ApplicationUser o) {
-        return contract.compare(this, o);
+    public int compareTo(final org.apache.isis.extensions.secman.api.user.ApplicationUser o) {
+        return contract.compare(this, (ApplicationUser) o);
     }
 
     @Override
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_allUsers.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_allUsers.java
index 9d5be86..395d9bf 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_allUsers.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_allUsers.java
@@ -21,6 +21,7 @@ package org.apache.isis.extensions.secman.jdo.dom.user;
 import java.util.Collection;
 
 import org.apache.isis.applib.annotation.MemberSupport;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
@@ -28,14 +29,14 @@ import lombok.RequiredArgsConstructor;
 @org.apache.isis.applib.annotation.Collection
 @RequiredArgsConstructor
 public class ApplicationUserManager_allUsers
-extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_allUsers<ApplicationUser>{
-    
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_allUsers{
+
     @SuppressWarnings("unused")
     private final ApplicationUserManager target;
-    
+
     @MemberSupport
     public Collection<ApplicationUser> coll() {
-        return super.doColl();        
+        return super.doColl();
     }
 
 }
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 f9e075d..0bc3acd 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
@@ -23,9 +23,9 @@ 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.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 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;
@@ -35,7 +35,7 @@ import lombok.RequiredArgsConstructor;
         associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newDelegateUser
-extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser<ApplicationRole>{
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser{
 
     private final ApplicationUserManager target;
 
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 ce4cd44..8b16866 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
@@ -24,9 +24,9 @@ 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.value.Password;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 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;
@@ -36,7 +36,7 @@ import lombok.RequiredArgsConstructor;
         associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newLocalUser
-extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser<ApplicationRole> {
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser {
 
     private final ApplicationUserManager target;
 
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 acd476a..0e371cc 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
@@ -21,6 +21,7 @@ package org.apache.isis.extensions.secman.jdo.dom.user;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Optional;
+import java.util.SortedSet;
 import java.util.function.Consumer;
 
 import javax.annotation.Nullable;
@@ -42,6 +43,7 @@ import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.encryption.PasswordEncryptionService;
 import org.apache.isis.extensions.secman.api.events.UserCreatedEvent;
+import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy;
 import org.apache.isis.extensions.secman.api.user.AccountType;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
@@ -54,7 +56,7 @@ import lombok.val;
 @Repository
 @Named("isis.ext.secman.ApplicationUserRepository")
 public class ApplicationUserRepository
-implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<ApplicationUser> {
+implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository {
 
     @Inject private FactoryService factoryService;
     @Inject private RepositoryService repository;
@@ -81,25 +83,31 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
      * </p>
      */
     @Override
-    public ApplicationUser findOrCreateUserByUsername(
-            final String username) {
+    public org.apache.isis.extensions.secman.api.user.ApplicationUser findOrCreateUserByUsername(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)),
+                    findOrCreateUserByUsernameNotCached(username),
             ApplicationUserRepository.class, "findOrCreateUserByUsername", username);
     }
 
+    private org.apache.isis.extensions.secman.api.user.ApplicationUser findOrCreateUserByUsernameNotCached(String username) {
+        return findByUsername(username).orElseGet(() -> newDelegateUser(username, null));
+    }
+
+
     // -- findByUsername
 
     public Optional<ApplicationUser> findByUsernameCached(final String username) {
         return queryResultsCacheProvider.get().execute(this::findByUsername,
-                ApplicationUserRepository.class, "findByUsernameCached", username);
+                ApplicationUserRepository.class, "findByUsernameCached", username)
+                .map(ApplicationUser.class::cast);
     }
 
     @Override
-    public Optional<ApplicationUser> findByUsername(final String username) {
+    public Optional<org.apache.isis.extensions.secman.api.user.ApplicationUser> findByUsername(final String username) {
         return repository.uniqueMatch(Query.named(ApplicationUser.class, "findByUsername")
-                .withParameter("username", username));
+                .withParameter("username", username))
+                .map(org.apache.isis.extensions.secman.api.user.ApplicationUser.class::cast);
     }
 
     // -- findByEmailAddress (programmatic)
@@ -117,7 +125,12 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     // -- findByName
 
     @Override
-    public Collection<ApplicationUser> find(final String search) {
+    public Collection<org.apache.isis.extensions.secman.api.user.ApplicationUser> find(final String search) {
+        //noinspection unchecked
+        return (Collection)find_(search);
+    }
+
+    private SortedSet<ApplicationUser> find_(String search) {
         final String regex = String.format("(?i).*%s.*", search.replace("*", ".*").replace("?", "."));
         return repository.allMatches(Query.named(ApplicationUser.class, "find")
                 .withParameter("regex", regex))
@@ -128,7 +141,12 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     // -- allUsers
 
     @Override
-    public Collection<ApplicationUser> findByAtPath(final String atPath) {
+    public Collection<org.apache.isis.extensions.secman.api.user.ApplicationUser> findByAtPath(final String atPath) {
+        //noinspection unchecked
+        return (Collection) findByAtPath_(atPath);
+    }
+
+    private Collection<ApplicationUser> findByAtPath_(String atPath) {
         return repository.allMatches(Query.named(ApplicationUser.class, "findByAtPath")
                 .withParameter("atPath", atPath))
                 .stream()
@@ -136,39 +154,60 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
     }
 
     @Override
-    public Collection<ApplicationUser> findByRole(
+    public Collection<org.apache.isis.extensions.secman.api.user.ApplicationUser> findByRole(
             org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) {
+        //noinspection unchecked
+        return (Collection)findByRole_(genericRole);
+    }
 
-        val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
+    private Collection<ApplicationUser> findByRole_(org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) {
+        ApplicationRole 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())
+    public Collection<org.apache.isis.extensions.secman.api.user.ApplicationUser> findByTenancy(
+            @NonNull final ApplicationTenancy genericTenancy) {
+        //noinspection unchecked
+        return (Collection)findByTenancy_(genericTenancy);
+    }
+
+    private Collection<ApplicationUser> findByTenancy_(org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy) {
+        return findByAtPath_(genericTenancy.getPath())
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
+
     // -- allUsers
 
     @Override
-    public Collection<ApplicationUser> allUsers() {
+    public Collection<org.apache.isis.extensions.secman.api.user.ApplicationUser> allUsers() {
+        //noinspection unchecked
+        return (Collection)allUsers_();
+    }
+
+    private Collection<ApplicationUser> allUsers_() {
         return repository.allInstances(ApplicationUser.class)
                 .stream()
                 .collect(_Sets.toUnmodifiableSorted());
     }
 
     @Override
-    public Collection<ApplicationUser> findMatching(final String search) {
+    public Collection<org.apache.isis.extensions.secman.api.user.ApplicationUser> findMatching(final String search) {
+        //noinspection unchecked
+        return (Collection)findMatching_(search);
+    }
+
+    private Collection<ApplicationUser> findMatching_(String search) {
         if (search != null && search.length() > 0) {
-            return find(search);
+            return find_(search);
         }
         return Collections.emptySortedSet();
     }
 
+
     // -- UPDATE USER STATE
 
     @Override
@@ -192,11 +231,12 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
         return configBean.getAdminUserName().equals(user.getUsername());
     }
 
+
     @Override
-    public ApplicationUser newUser(
+    public org.apache.isis.extensions.secman.api.user.ApplicationUser newUser(
             @NonNull String username,
             @Nullable AccountType accountType,
-            Consumer<ApplicationUser> beforePersist) {
+            Consumer<org.apache.isis.extensions.secman.api.user.ApplicationUser> beforePersist) {
 
         val user = newApplicationUser();
         user.setUsername(username);
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermission.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermission.java
index 1df52e1..a47635f 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermission.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermission.java
@@ -68,6 +68,7 @@ import lombok.Getter;
 import lombok.Setter;
 import lombok.experimental.UtilityClass;
 
+@SuppressWarnings("JpaQlInspection")
 @Entity
 @Table(
         schema = "isisExtensionsSecman",
@@ -122,8 +123,7 @@ import lombok.experimental.UtilityClass;
 )
 public class ApplicationPermission
 implements
-    org.apache.isis.extensions.secman.api.permission.ApplicationPermission<ApplicationUser, ApplicationRole>,
-    Comparable<ApplicationPermission> {
+    org.apache.isis.extensions.secman.api.permission.ApplicationPermission {
 
     @Inject transient ApplicationFeatureRepository featureRepository;
 
@@ -139,17 +139,25 @@ implements
     // -- ROLE
 
     @Role
+    @SuppressWarnings("JpaAttributeTypeInspection")
     @JoinColumn(name="roleId", nullable=false)
     @Getter(onMethod = @__(@Override))
-    @Setter(onMethod = @__(@Override))
-    @SuppressWarnings("JpaAttributeTypeInspection")
     private ApplicationRole role;
 
+    public void setRole(ApplicationRole role) {
+        this.role = role;
+    }
+
+    @Override
+    public void setRole(org.apache.isis.extensions.secman.api.role.ApplicationRole applicationRole) {
+        setRole((ApplicationRole) applicationRole);
+    }
+
 
     // -- FEATURE FQN
 
     @FeatureFqn
-    @Column(nullable=false)
+    @Column(nullable=false, length = FeatureFqn.MAX_LENGTH)
     @Getter(onMethod = @__(@Override))
     @Setter(onMethod = @__(@Override))
     private String featureFqn;
@@ -218,8 +226,8 @@ implements
             .thenUse("mode", ApplicationPermission::getMode);
 
     @Override
-    public int compareTo(final ApplicationPermission other) {
-        return contract.compare(this, other);
+    public int compareTo(final org.apache.isis.extensions.secman.api.permission.ApplicationPermission other) {
+        return contract.compare(this, (ApplicationPermission) other);
     }
 
     @Override
@@ -242,7 +250,7 @@ implements
     public static class DefaultComparator implements Comparator<ApplicationPermission> {
         @Override
         public int compare(final ApplicationPermission o1, final ApplicationPermission o2) {
-            return Objects.compare(o1, o2, (a, b) -> a.compareTo(b) );
+            return Objects.compare(o1, o2, ApplicationPermission::compareTo);
         }
     }
 
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermissionRepository.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermissionRepository.java
index 787fc8a..cfac356 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermissionRepository.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/permission/ApplicationPermissionRepository.java
@@ -58,13 +58,13 @@ import lombok.val;
 @Service
 @Named("isis.ext.secman.ApplicationPermissionRepository")
 public class ApplicationPermissionRepository
-implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository<ApplicationPermission> {
+implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository {
 
     @Inject private RepositoryService repository;
     @Inject private ApplicationFeatureRepository featureRepository;
     @Inject private FactoryService factory;
     @Inject private MessageService messages;
-    
+
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
     @Override
@@ -87,7 +87,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
     // -- findByUser (programmatic)
     public List<ApplicationPermission> findByUserCached(@NonNull final ApplicationUser user) {
-        return queryResultsCacheProvider.get().execute(this::findByUser, 
+        return queryResultsCacheProvider.get().execute(this::findByUser,
                 ApplicationPermissionRepository.class, "findByUserCached", user);
     }
 
@@ -96,11 +96,11 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     }
 
     @Inject private ApplicationUserRepository userRepository;
-    
+
     private List<ApplicationPermission> findByUser(final String username) {
-        
+
         //TODO named query PERMISSION_BY_USER not working yet, using workaround  ...
-        
+
         return userRepository.findByUsername(username)
         .map(ApplicationUser::getRoles)
         .map(_NullSafe::stream)
@@ -129,8 +129,8 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
         // put into query cache (so that this method can be safely called in a tight loop)
         val permissions =
                 queryResultsCacheProvider.get().execute(
-                        this::permissionsByPermissionValue, 
-                        ApplicationPermissionRepository.class, "findByUserAndPermissionValue", 
+                        this::permissionsByPermissionValue,
+                        ApplicationPermissionRepository.class, "findByUserAndPermissionValue",
                         username);
 
         // now simply return the permission from the required value (if it exists)
@@ -139,16 +139,16 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
                 ? Optional.of(applicationPermissions.get(0))
                         : Optional.empty();
     }
-    
+
     private ListMultimap<ApplicationPermissionValue, ApplicationPermission> permissionsByPermissionValue(
             final String username) {
 
         // only username (and not permissionValue) is the key
         // (we are obtaining all the perms for this user)
-        
+
         val permissionsByPermissionValue =
                 _Multimaps.<ApplicationPermissionValue, ApplicationPermission>newListMultimap();
-        
+
         val permissions = findByUser(username);
 
         _NullSafe.stream(permissions)
@@ -166,13 +166,13 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             ApplicationPermissionRule rule,
             ApplicationFeatureSort type) {
-        return queryResultsCacheProvider.get().execute(this::findByRoleAndRuleAndFeatureType, 
-                ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureTypeCached", 
+        return queryResultsCacheProvider.get().execute(this::findByRoleAndRuleAndFeatureType,
+                ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureTypeCached",
                 role, rule, type);
     }
 
     public Collection<ApplicationPermission> findByRoleAndRuleAndFeatureType(
-            org.apache.isis.extensions.secman.api.role.ApplicationRole role, 
+            org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             final ApplicationPermissionRule rule,
             final ApplicationFeatureSort featureSort) {
         return repository.allMatches(Query.named(
@@ -275,7 +275,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
         repository.persist(permission);
         return permission;
     }
-    
+
     @Override
     public ApplicationPermission newPermission(
             final org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole,
@@ -288,16 +288,16 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
         val featureId = ApplicationFeatureId.newFeature(featurePackage, featureClassName, featureMemberName);
         return newPermission(genericRole, rule, mode, featureId);
     }
-    
+
     @Override
     public ApplicationPermission newPermission(
             final org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole,
-            final ApplicationPermissionRule rule, 
-            final ApplicationPermissionMode mode, 
+            final ApplicationPermissionRule rule,
+            final ApplicationPermissionMode mode,
             final ApplicationFeatureId featureId) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
-        
+
         val featureSort = featureId.getSort();
         val featureFqn = featureId.getFullyQualifiedName();
 
@@ -332,19 +332,19 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     @Override
     public Collection<ApplicationPermission> findOrphaned() {
 
-        val featureNamesKnownToTheMetamodel =  
+        val featureNamesKnownToTheMetamodel =
                 featureRepository.getFeatureIdentifiersByName().keySet();
 
         val orphaned = _Lists.<ApplicationPermission>newArrayList();
 
         for (val permission : allPermissions()) {
-            
+
             val featId = permission.asFeatureId().orElse(null);
             if(featId==null) {
                 orphaned.add(permission);
                 continue;
             }
-            
+
             if(!featureNamesKnownToTheMetamodel.contains(featId.getFullyQualifiedName())) {
                 orphaned.add(permission);
             }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRole.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRole.java
index b173c15..681cade 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRole.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRole.java
@@ -58,6 +58,7 @@ import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPoin
 import lombok.Getter;
 import lombok.Setter;
 
+@SuppressWarnings("JpaQlInspection")
 @Entity
 @Table(
         schema = "isisExtensionsSecman",
@@ -92,7 +93,7 @@ import lombok.Setter;
         )
 public class ApplicationRole
 implements
-    org.apache.isis.extensions.secman.api.role.ApplicationRole<ApplicationUser, ApplicationRole> {
+    org.apache.isis.extensions.secman.api.role.ApplicationRole {
 
     @Inject private transient ApplicationPermissionRepository applicationPermissionRepository;
 
@@ -186,8 +187,8 @@ implements
 
 
     @Override
-    public int compareTo(final ApplicationRole o) {
-        return comparator.compare(this, o);
+    public int compareTo(final org.apache.isis.extensions.secman.api.role.ApplicationRole o) {
+        return comparator.compare(this, (ApplicationRole) o);
     }
 
     @Override
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRoleRepository.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRoleRepository.java
index cdc782e..94557ab 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRoleRepository.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/role/ApplicationRoleRepository.java
@@ -43,21 +43,21 @@ import lombok.val;
 
 @Service
 @Named("isis.ext.secman.ApplicationRoleRepository")
-public class ApplicationRoleRepository 
-implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<ApplicationRole> {
+public class ApplicationRoleRepository
+implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository {
 
     @Inject private FactoryService factoryService;
     @Inject private RepositoryService repository;
     @Inject private SecmanConfiguration configBean;
-    
+
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
 
-    
+
     @Override
     public ApplicationRole newApplicationRole() {
         return factoryService.detachedEntity(new ApplicationRole());
     }
-    
+
     @Override
     public Optional<ApplicationRole> findByNameCached(final String name) {
         return queryResultsCacheProvider.get().execute(()->findByName(name),
@@ -75,7 +75,7 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
 
     @Override
     public Collection<ApplicationRole> findNameContaining(final String search) {
-        
+
         if(search != null && search.length() > 0) {
             String nameRegex = String.format("(?i).*%s.*", search.replace("*", ".*").replace("?", "."));
             return repository.allMatches(
@@ -118,28 +118,28 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
 
     @Override
     public void addRoleToUser(
-            org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole, 
+            org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole,
             org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
         val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
         user.getRoles().add(role);
         role.getUsers().add(user);
-        
+
         // user is the relation owner
         repository.persistAndFlush(user);
     }
-    
+
     @Override
     public void removeRoleFromUser(
             org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole,
             org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
         val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
         user.getRoles().remove(role);
         role.getUsers().remove(user);
-        
+
         // user is the relation owner
         repository.persistAndFlush(user);
     }
@@ -152,9 +152,9 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
 
     @Override
     public void deleteRole(org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
-        
+
         role.getUsers().clear();
         val permissions = role.getPermissions();
         for (val permission : permissions) {
@@ -164,11 +164,5 @@ implements org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository<
         repository.removeAndFlush(role);
     }
 
-    @Override
-    public Collection<ApplicationRole> getRoles(
-            org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
-        val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
-        return user.getRoles();
-    }
 
 }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancy.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancy.java
index 0fd2cfa..1f8b441 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancy.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancy.java
@@ -50,6 +50,7 @@ import org.apache.isis.extensions.secman.jpa.dom.constants.NamedQueryNames;
 import lombok.Getter;
 import lombok.Setter;
 
+@SuppressWarnings("JpaQlInspection")
 @Entity
 @Table(
         schema = "isisExtensionsSecman",
@@ -86,9 +87,7 @@ import lombok.Setter;
         bookmarking = BookmarkPolicy.AS_ROOT
         )
 public class ApplicationTenancy
-implements
-    Comparable<ApplicationTenancy>,
-    org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy {
+implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy {
 
     // -- name (property, title)
 
@@ -195,8 +194,8 @@ implements
     }
 
     @Override
-    public int compareTo(final ApplicationTenancy o) {
-        return comparator.compare(this, o);
+    public int compareTo(final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy o) {
+        return comparator.compare(this, (ApplicationTenancy) o);
     }
 
 }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancyRepository.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancyRepository.java
index e15e9c9..b69ce59 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancyRepository.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/tenancy/ApplicationTenancyRepository.java
@@ -41,19 +41,19 @@ import lombok.val;
 
 @Service
 @Named("isis.ext.secman.ApplicationTenancyRepository")
-public class ApplicationTenancyRepository 
-implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepository<ApplicationTenancy> {
+public class ApplicationTenancyRepository
+implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepository {
 
     @Inject private FactoryService factory;
     @Inject private RepositoryService repository;
-    
+
     @Inject private javax.inject.Provider<QueryResultsCache> queryResultsCacheProvider;
-    
+
     @Override
     public ApplicationTenancy newApplicationTenancy() {
         return factory.detachedEntity(new ApplicationTenancy());
     }
-    
+
     // -- findByNameOrPathMatching
 
     @Override
@@ -140,7 +140,7 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
         return tenancy;
     }
 
-    // -- 
+    // --
 
     @Override
     public Collection<ApplicationTenancy> allTenancies() {
@@ -158,17 +158,17 @@ implements org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepos
                 .map(ApplicationTenancy.class::cast)
                 .collect(_Sets.toUnmodifiableSorted());
     }
-    
+
     @Override
     public void setTenancyOnUser(
-            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy, 
+            @NonNull final org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy genericTenancy,
             @NonNull final org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
         val tenancy = _Casts.<ApplicationTenancy>uncheckedCast(genericTenancy);
         val user = _Casts.<ApplicationUser>uncheckedCast(genericUser);
         // no need to add to users set, since will be done by JDO/DN.
         user.setAtPath(tenancy.getPath());
     }
-    
+
     @Override
     public void clearTenancyOnUser(
             @NonNull final org.apache.isis.extensions.secman.api.user.ApplicationUser genericUser) {
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 27f9e8e..cf21971 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
@@ -64,6 +64,7 @@ import lombok.Getter;
 import lombok.Setter;
 import lombok.val;
 
+@SuppressWarnings("JpaQlInspection")
 @Entity
 @Table(
         schema = "isisExtensionsSecman",
@@ -109,7 +110,7 @@ import lombok.val;
         bookmarking = BookmarkPolicy.AS_ROOT
         )
 public class ApplicationUser
-        implements org.apache.isis.extensions.secman.api.user.ApplicationUser<ApplicationUser, ApplicationRole> {
+        implements org.apache.isis.extensions.secman.api.user.ApplicationUser {
 
     @Inject private transient ApplicationPermissionRepository applicationPermissionRepository;
     @Inject private transient UserService userService;
@@ -282,8 +283,8 @@ public class ApplicationUser
 
 
     @Override
-    public int compareTo(final ApplicationUser o) {
-        return contract.compare(this, o);
+    public int compareTo(final org.apache.isis.extensions.secman.api.user.ApplicationUser o) {
+        return contract.compare(this, (ApplicationUser) o);
     }
 
     @Override
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 f39cff0..66f3bc8 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
@@ -56,7 +56,7 @@ import lombok.val;
 @Service
 @Named("isis.ext.secman.ApplicationUserRepository")
 public class ApplicationUserRepository
-implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<ApplicationUser> {
+implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository {
 
     @Inject private FactoryService factoryService;
     @Inject private RepositoryService repository;
@@ -95,13 +95,15 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository<
 
     public Optional<ApplicationUser> findByUsernameCached(final String username) {
         return queryResultsCacheProvider.get().execute(this::findByUsername,
-                ApplicationUserRepository.class, "findByUsernameCached", username);
+                ApplicationUserRepository.class, "findByUsernameCached", username)
+                .map(ApplicationUser.class::cast);
     }
 
     @Override
-    public Optional<ApplicationUser> findByUsername(final String username) {
+    public Optional<org.apache.isis.extensions.secman.api.user.ApplicationUser> findByUsername(final String username) {
         return repository.uniqueMatch(Query.named(ApplicationUser.class, NamedQueryNames.USER_BY_USERNAME)
-                .withParameter("username", username));
+                .withParameter("username", username))
+                .map(org.apache.isis.extensions.secman.api.user.ApplicationUser.class::cast);
     }
 
     // -- findByEmailAddress (programmatic)
diff --git a/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleExtSecmanShiroRealm.java b/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleExtSecmanShiroRealm.java
index 1c739a4..b633e6c 100644
--- a/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleExtSecmanShiroRealm.java
+++ b/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleExtSecmanShiroRealm.java
@@ -246,7 +246,7 @@ public class IsisModuleExtSecmanShiroRealm extends AuthorizingRealm implements S
                 val applicationUser = applicationUserRepository.findByUsername(username).orElse(null);
                 return PrincipalForApplicationUser.from(applicationUser);
             }
-            @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+            @Inject private ApplicationUserRepository applicationUserRepository;
         });
     }
 
@@ -258,7 +258,7 @@ public class IsisModuleExtSecmanShiroRealm extends AuthorizingRealm implements S
                 val applicationUser = applicationUserRepository.findOrCreateUserByUsername(username);
                 return PrincipalForApplicationUser.from(applicationUser);
             }
-            @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+            @Inject private ApplicationUserRepository applicationUserRepository;
         });
     }