You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/03/03 13:53:51 UTC

[isis] branch ISIS-2553_rational.id created (now 15b79a4)

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

ahuber pushed a change to branch ISIS-2553_rational.id
in repository https://gitbox.apache.org/repos/asf/isis.git.


      at 15b79a4  ISIS-2553: promote ApplicationFeatureId to applib

This branch includes the following new commits:

     new 15b79a4  ISIS-2553: promote ApplicationFeatureId to applib

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



[isis] 01/01: ISIS-2553: promote ApplicationFeatureId to applib

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

ahuber pushed a commit to branch ISIS-2553_rational.id
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 15b79a43ef0d178f879b79a6e509a0f3571cc401
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Mar 3 14:53:32 2021 +0100

    ISIS-2553: promote ApplicationFeatureId to applib
    
    (still needs a lot of cleanup)
---
 .../services/appfeat/ApplicationFeatureId.java     | 172 +++++----------------
 .../appfeat/ApplicationFeatureRepository.java      |   5 +
 .../services/appfeat/ApplicationFeatureType.java   |  17 +-
 .../services/appfeat/ApplicationFeature.java       |   5 +-
 .../ApplicationFeatureRepositoryDefault.java       |  73 ++++-----
 .../core/metamodel/services/appfeat/_Asserts.java  |  50 ++++++
 .../metamodel/services/appfeat/_Predicates.java    |  50 ++++++
 .../metamodel/MetaModelServiceDefault.java         |   4 +-
 .../specloader/SpecificationLoaderDefault.java     |   2 +-
 .../services/appfeat/ApplicationFeatureIdTest.java |  14 +-
 .../ApplicationFeatureRepositoryDefaultTest.java   |   1 +
 .../services/appfeat/ApplicationFeatureTest.java   |   1 +
 .../appfeat/ApplicationFeatureTypeTest.java        |  48 +++---
 .../secman/api/authorizor/AuthorizorSecman.java    |   2 +-
 .../api/permission/ApplicationPermission.java      |   4 +-
 .../ApplicationPermissionRepository.java           |  14 +-
 .../api/permission/ApplicationPermissionValue.java |   2 +-
 .../permission/ApplicationPermissionValueSet.java  |   2 +-
 .../permission/PermissionsEvaluationService.java   |   2 +-
 .../PermissionsEvaluationServiceAbstract.java      |   2 +-
 .../secman/api/role/ApplicationRole.java           |   7 +-
 .../secman/model/app/feature/ApplicationClass.java |   2 +-
 .../model/app/feature/ApplicationClassAction.java  |   2 +-
 .../app/feature/ApplicationClassCollection.java    |   2 +-
 .../model/app/feature/ApplicationClassMember.java  |   2 +-
 .../app/feature/ApplicationClassProperty.java      |   2 +-
 .../app/feature/ApplicationFeatureViewModel.java   |   4 +-
 .../model/app/feature/ApplicationPackage.java      |   4 +-
 .../app/feature/ApplicationPermission_feature.java |   2 +-
 .../user/ApplicationUser_filterPermissions.java    |   6 +-
 .../app/user/ApplicationUser_permissions.java      |   4 +-
 .../model/app/user/UserPermissionViewModel.java    |   4 +-
 .../ApplicationOrphanedPermissionManager.java      |   9 +-
 ...OrphanedPermissionManager_relocateSelected.java |   2 +-
 .../permission/ApplicationPermission_allow.java    |   8 +-
 .../permission/ApplicationPermission_changing.java |   8 +-
 .../permission/ApplicationPermission_delete.java   |  10 +-
 .../ApplicationPermission_updateRole.java          |  12 +-
 .../dom/permission/ApplicationPermission_veto.java |  12 +-
 .../permission/ApplicationPermission_viewing.java  |  12 +-
 .../model/dom/role/ApplicationRole_addAction.java  |   8 +-
 .../model/dom/role/ApplicationRole_addClass.java   |   8 +-
 .../dom/role/ApplicationRole_addCollection.java    |   8 +-
 .../model/dom/role/ApplicationRole_addPackage.java |   8 +-
 ...ion.java => ApplicationRole_addPermission.java} |  89 +++++++----
 .../dom/role/ApplicationRole_addProperty.java      |   8 +-
 .../model/dom/role/ApplicationRole_addUser.java    |   8 +-
 .../dom/role/ApplicationRole_removePermission.java |  12 +-
 .../role/ApplicationRole_removePermissions.java    |   8 +-
 .../model/dom/role/ApplicationRole_removeUser.java |  10 +-
 .../dom/role/ApplicationRole_removeUsers.java      |   8 +-
 .../role/ApplicationRole_updateDescription.java    |  12 +-
 .../model/dom/role/ApplicationRole_updateName.java |  12 +-
 .../dom/tenancy/ApplicationTenancy_addChild.java   |   6 +-
 .../dom/tenancy/ApplicationTenancy_addUser.java    |   8 +-
 .../dom/tenancy/ApplicationTenancy_delete.java     |   4 +-
 .../tenancy/ApplicationTenancy_removeChild.java    |  12 +-
 .../dom/tenancy/ApplicationTenancy_removeUser.java |  12 +-
 .../dom/tenancy/ApplicationTenancy_updateName.java |  14 +-
 .../tenancy/ApplicationTenancy_updateParent.java   |   8 +-
 .../dom/tenancy/ApplicationTenancy_users.java      |   4 +-
 .../ApplicationUserManager_newDelegateUser.java    |   6 +-
 .../user/ApplicationUserManager_newLocalUser.java  |   6 +-
 .../model/dom/user/ApplicationUser_addRole.java    |  12 +-
 .../model/dom/user/ApplicationUser_delete.java     |   6 +-
 .../model/dom/user/ApplicationUser_duplicate.java  |   6 +-
 .../model/dom/user/ApplicationUser_lock.java       |  10 +-
 .../model/dom/user/ApplicationUser_removeRole.java |  12 +-
 .../dom/user/ApplicationUser_removeRoles.java      |   8 +-
 .../dom/user/ApplicationUser_resetPassword.java    |  10 +-
 .../model/dom/user/ApplicationUser_unlock.java     |   8 +-
 .../user/ApplicationUser_updateAccountType.java    |  10 +-
 .../dom/user/ApplicationUser_updateAtPath.java     |   8 +-
 .../user/ApplicationUser_updateEmailAddress.java   |  10 +-
 .../model/dom/user/ApplicationUser_updateName.java |  18 +--
 .../dom/user/ApplicationUser_updatePassword.java   |  18 +--
 .../user/ApplicationUser_updatePhoneNumber.java    |  10 +-
 .../dom/user/ApplicationUser_updateUsername.java   |   8 +-
 .../secman/model/dom/user/HasUsername_open.java    |  10 +-
 .../jdo/dom/permission/ApplicationPermission.java  |   4 +-
 .../ApplicationPermissionRepository.java           |  34 ++--
 .../secman/jdo/dom/user/ApplicationUser.java       |   2 +-
 .../AbstractRoleAndPermissionsFixtureScript.java   |   2 +-
 .../jpa/dom/permission/ApplicationPermission.java  |   4 +-
 .../ApplicationPermissionRepository.java           |  20 ++-
 .../secman/jpa/dom/user/ApplicationUser.java       |   2 +-
 .../AbstractRoleAndPermissionsFixtureScript.java   |   2 +-
 .../secman/shiro/PermissionForMember.java          |   2 +-
 88 files changed, 593 insertions(+), 506 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java
similarity index 78%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java
index f6ce177..f465792 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.services.appfeat;
+package org.apache.isis.applib.services.appfeat;
 
 import java.io.Serializable;
 import java.util.Collections;
@@ -24,7 +24,6 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.function.Function;
-import java.util.function.Predicate;
 
 import static java.util.Comparator.comparing;
 import static java.util.Comparator.naturalOrder;
@@ -33,7 +32,6 @@ import static java.util.Comparator.nullsFirst;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Value;
-import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
 import org.apache.isis.applib.util.ObjectContracts;
@@ -42,7 +40,9 @@ import org.apache.isis.applib.util.ToString;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 
+import lombok.Getter;
 import lombok.NonNull;
+import lombok.Setter;
 import lombok.val;
 
 /**
@@ -118,9 +118,7 @@ implements
     }
 
     public static ApplicationFeatureId newClass(final String classFqn) {
-        final ApplicationFeatureId featureId = new ApplicationFeatureId(ApplicationFeatureType.CLASS);
-        featureId.type.init(featureId, classFqn);
-        return featureId;
+        return new ApplicationFeatureId(ApplicationFeatureType.CLASS, classFqn);
     }
 
     public static ApplicationFeatureId newMember(final String classFqn, final String memberName) {
@@ -132,9 +130,7 @@ implements
     }
 
     public static ApplicationFeatureId newMember(final String fullyQualifiedName) {
-        final ApplicationFeatureId featureId = new ApplicationFeatureId(ApplicationFeatureType.MEMBER);
-        featureId.type.init(featureId, fullyQualifiedName);
-        return featureId;
+        return new ApplicationFeatureId(ApplicationFeatureType.MEMBER, fullyQualifiedName);
     }
 
     /**
@@ -151,10 +147,7 @@ implements
         return new ApplicationFeatureId(_Strings.base64UrlDecode(encodedString));
     }
 
-
-    // //////////////////////////////////////
-
-    // -- constructor
+    // -- CONSTRUCTOR
 
     private ApplicationFeatureId(final String asString) {
         final Iterator<String> iterator = _Strings.splitThenStream(asString, ":").iterator();
@@ -163,8 +156,8 @@ implements
     }
 
     /**
-     * Must be called by {@link ApplicationFeatureType#init(ApplicationFeatureId, String)} immediately afterwards
-     * to fully initialize.
+     * Must be called by {@link ApplicationFeatureType#init(ApplicationFeatureId, String)} 
+     * immediately afterwards to fully initialize.
      */
     ApplicationFeatureId(final ApplicationFeatureType type) {
         this.type = type;
@@ -174,11 +167,8 @@ implements
         type.init(this, fullyQualifiedName);
     }
 
-
-
-    // //////////////////////////////////////
-
-    // -- identification
+    // -- IDENTIFICATION
+    
     /**
      * having a title() method (rather than using @Title annotation) is necessary as a workaround to be able to use
      * wrapperFactory#unwrap(...) method, which is otherwise broken in Isis 1.6.0
@@ -189,10 +179,7 @@ implements
         return buf.toString();
     }
 
-
-    // //////////////////////////////////////
-
-    // -- fullyQualifiedName (property)
+    // -- PROPERTIES
 
     @Programmatic
     public String getFullyQualifiedName() {
@@ -207,10 +194,6 @@ implements
         return buf.toString();
     }
 
-
-
-    // -- objectSpecId (property)
-
     @Programmatic
     public String getLogicalTypeName() {
         if (getTypeSimpleName() == null) {
@@ -226,67 +209,16 @@ implements
         return buf.toString();
     }
 
+    @Getter ApplicationFeatureType type;
 
+    @Programmatic 
+    @Getter @Setter private String namespace;
 
-    // //////////////////////////////////////
-
-    // -- type (property)
-    ApplicationFeatureType type;
-
-    public ApplicationFeatureType getType() {
-        return type;
-    }
-
-
-    // //////////////////////////////////////
-
-    // -- namespace (property)
-    private String namespace;
-
-    @Programmatic
-    public String getNamespace() {
-        return namespace;
-    }
-
-    void setNamespace(final String namespace) {
-        this.namespace = namespace;
-    }
-
-
-    // //////////////////////////////////////
-
-    // -- className (property, optional)
-
-    private String typeSimpleName;
-
-    @Programmatic
-    public String getTypeSimpleName() {
-        return typeSimpleName;
-    }
-
-    void setTypeSimpleName(final String className) {
-        this.typeSimpleName = className;
-    }
-
-
-    // //////////////////////////////////////
-
-    // -- memberName (property, optional)
-    private String memberName;
-
-    @Programmatic
-    public String getMemberName() {
-        return memberName;
-    }
-
-    void setMemberName(final String memberName) {
-        this.memberName = memberName;
-    }
-
-
-    // //////////////////////////////////////
+    @Programmatic 
+    @Getter @Setter private String typeSimpleName;
 
-    // -- Package or Class: getParentPackageId
+    @Programmatic 
+    @Getter @Setter private String memberName;
 
     /**
      * The {@link ApplicationFeatureId id} of the parent package of this
@@ -312,12 +244,6 @@ implements
         }
     }
 
-
-
-    // //////////////////////////////////////
-
-    // -- Member: getParentClassId
-
     /**
      * The {@link ApplicationFeatureId id} of the member's class.
      */
@@ -327,10 +253,7 @@ implements
         return newClass(classFqn);
     }
 
-
-    // //////////////////////////////////////
-
-    // -- asString, asEncodedString
+    // -- ENCODING
 
     @Programmatic
     public String asString() {
@@ -341,7 +264,6 @@ implements
     public String asEncodedString() {
         return _Strings.base64UrlEncode(asString());
     }
-    
 
     // //////////////////////////////////////
 
@@ -362,36 +284,6 @@ implements
 
     // //////////////////////////////////////
 
-    // -- Predicates
-
-    public static class Predicates {
-        private Predicates(){}
-
-        public static Predicate<ApplicationFeatureId> isClassContaining(
-                final ApplicationMemberType memberType, final ApplicationFeatureRepositoryDefault applicationFeatures) {
-            return new Predicate<ApplicationFeatureId>() {
-                @Override
-                public boolean test(final ApplicationFeatureId input) {
-                    if(input.getType() != ApplicationFeatureType.CLASS) {
-                        return false;
-                    }
-                    final ApplicationFeature feature = applicationFeatures.findFeature(input);
-                    if(feature == null) {
-                        return false;
-                    }
-                    return memberType == null || !feature.membersOf(memberType).isEmpty();
-                }
-            };
-        }
-
-        public static Predicate<ApplicationFeatureId> isClassRecursivelyWithin(final ApplicationFeatureId packageId) {
-            return (ApplicationFeatureId input) -> input.getParentIds().contains(packageId);
-        }
-    }
-
-
-    // //////////////////////////////////////
-
     // -- Comparators
     public static final class Comparators {
         private Comparators(){}
@@ -441,10 +333,7 @@ implements
         return parentIds;
     }
 
-
-    // //////////////////////////////////////
-
-    // -- equals, hashCode, compareTo, toString
+    // -- OBJECT CONTRACT
 
     private static final Comparator<ApplicationFeatureId> byType =
             comparing(ApplicationFeatureId::getType, nullsFirst(naturalOrder()));
@@ -510,5 +399,26 @@ implements
         return newFeature(namespace, this.getTypeSimpleName(), this.getMemberName()); 
     }
 
+    @Deprecated // duplicate
+    public static ApplicationFeatureId createPackage(String fqn) {
+        val feat = new ApplicationFeatureId(ApplicationFeatureType.PACKAGE);
+        ApplicationFeatureType.PACKAGE.init(feat, fqn);
+        return feat;
+    }
+    
+    @Deprecated // duplicate
+    public static ApplicationFeatureId createClass(String fqn) {
+        val feat = new ApplicationFeatureId(ApplicationFeatureType.CLASS);
+        ApplicationFeatureType.CLASS.init(feat, fqn);
+        return feat;
+    }
+    
+    @Deprecated // duplicate
+    public static ApplicationFeatureId createMember(String fqn) {
+        val feat = new ApplicationFeatureId(ApplicationFeatureType.MEMBER);
+        ApplicationFeatureType.MEMBER.init(feat, fqn);
+        return feat;
+    }
+
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureRepository.java b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureRepository.java
index fbc1910..558126f 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureRepository.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureRepository.java
@@ -18,8 +18,11 @@
  */
 package org.apache.isis.applib.services.appfeat;
 
+import java.util.Map;
 import java.util.SortedSet;
 
+import org.apache.isis.applib.Identifier;
+
 /**
  * Provides the access to string representations of the packages, classes and
  * class members (collectively: "application features") of the domain classes
@@ -46,4 +49,6 @@ public interface ApplicationFeatureRepository  {
             String className,
             ApplicationMemberType memberType);
 
+    Map<String, ApplicationFeatureId> getFeatureIdentifiersByName();
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureType.java b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureType.java
similarity index 89%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureType.java
rename to api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureType.java
index 441b36a..81415a9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureType.java
@@ -16,9 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.services.appfeat;
+package org.apache.isis.applib.services.appfeat;
 
-import org.apache.isis.core.metamodel.commons.StringExtensions;
+import org.apache.isis.commons.internal.base._Strings;
 
 public enum ApplicationFeatureType {
     
@@ -76,40 +76,41 @@ public enum ApplicationFeatureType {
     public boolean hideClassName() {
         return this == ApplicationFeatureType.PACKAGE;
     }
+    
     public boolean hideMember() {
         return this == ApplicationFeatureType.PACKAGE || this == ApplicationFeatureType.CLASS;
     }
 
     abstract void init(ApplicationFeatureId applicationFeatureId, String fullyQualifiedName);
 
-    static void ensurePackage(final ApplicationFeatureId feature) {
+    public static void ensurePackage(final ApplicationFeatureId feature) {
         if(feature.type != ApplicationFeatureType.PACKAGE) {
             throw new IllegalStateException("Can only be called for a package; " + feature.toString());
         }
     }
 
-    static void ensurePackageOrClass(final ApplicationFeatureId applicationFeatureId) {
+    public static void ensurePackageOrClass(final ApplicationFeatureId applicationFeatureId) {
         if(applicationFeatureId.type != ApplicationFeatureType.PACKAGE && applicationFeatureId.type != ApplicationFeatureType.CLASS) {
             throw new IllegalStateException("Can only be called for a package or a class; " + applicationFeatureId.toString());
         }
     }
 
-    static void ensureClass(final ApplicationFeatureId feature) {
+    public static void ensureClass(final ApplicationFeatureId feature) {
         if(feature.type != ApplicationFeatureType.CLASS) {
             throw new IllegalStateException("Can only be called for a class; " + feature.toString());
         }
     }
 
-    static void ensureMember(final ApplicationFeatureId feature) {
+    public static void ensureMember(final ApplicationFeatureId feature) {
         if(feature.type != ApplicationFeatureType.MEMBER) {
             throw new IllegalStateException("Can only be called for a member; " + feature.toString());
         }
     }
 
-
     @Override
     public String toString() {
-        return StringExtensions.capitalize(name());
+        return _Strings.capitalize(name());
     }
+    
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeature.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeature.java
index b43ffbf..af36106 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeature.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeature.java
@@ -28,7 +28,9 @@ import javax.enterprise.inject.Vetoed;
 import org.apache.isis.applib.IsisModuleApplib;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.annotation.Value;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
@@ -193,7 +195,7 @@ public class ApplicationFeature implements Comparable<ApplicationFeature> {
 
             return (final ApplicationFeature input) ->
             input.getContents().stream() // all the classes in this package
-            .anyMatch(ApplicationFeatureId.Predicates.isClassContaining(memberType, applicationFeatures));
+            .anyMatch(_Predicates.isClassContaining(memberType, applicationFeatures));
         }
     }
 
@@ -230,6 +232,7 @@ public class ApplicationFeature implements Comparable<ApplicationFeature> {
     public String toString() {
         return toString.toString(this);
     }
+    
 
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
index 8174e00..b718d1d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
@@ -20,10 +20,13 @@ package org.apache.isis.core.metamodel.services.appfeat;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
+import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
@@ -34,7 +37,9 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Sets;
@@ -62,9 +67,11 @@ import lombok.extern.log4j.Log4j2;
 @Service
 @Named("isis.metamodel.ApplicationFeatureRepositoryDefault")
 @Log4j2
-public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRepository {
+public class ApplicationFeatureRepositoryDefault 
+implements ApplicationFeatureRepository {
 
     // -- caches
+    private Map<String, ApplicationFeatureId> featureIdentifiersByName;
     final SortedMap<ApplicationFeatureId, ApplicationFeature> packageFeatures = _Maps.newTreeMap();
     private final SortedMap<ApplicationFeatureId, ApplicationFeature> classFeatures = _Maps.newTreeMap();
     private final SortedMap<ApplicationFeatureId, ApplicationFeature> memberFeatures = _Maps.newTreeMap();
@@ -115,9 +122,22 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
             return;
         }
         initializationState = InitializationState.INITIALIZED;
+        
         for (val spec : specificationLoader.snapshotSpecifications()) {
             createApplicationFeaturesFor(spec);
         }
+        
+        val featuresByName = new HashMap<String, ApplicationFeatureId>();
+        visitFeatureIdentifierByName(packageFeatures, featuresByName::put);
+        visitFeatureIdentifierByName(classFeatures, featuresByName::put);
+        visitFeatureIdentifierByName(memberFeatures, featuresByName::put);
+        this.featureIdentifiersByName = Collections.unmodifiableMap(featuresByName);
+    }
+    
+    private void visitFeatureIdentifierByName(
+            final Map<ApplicationFeatureId, ApplicationFeature> map, 
+            final BiConsumer<String, ApplicationFeatureId> onEntry) {
+        map.forEach((k, v)->onEntry.accept(k.toString(), k));
     }
 
     void createApplicationFeaturesFor(final ObjectSpecification spec) {
@@ -137,8 +157,8 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
             return;
         }
 
-        final String specIdString = spec.getLogicalTypeName();
-        final ApplicationFeatureId classFeatureId = ApplicationFeatureId.newClass(specIdString);
+        final String logicalTypeName = spec.getLogicalTypeName();
+        final ApplicationFeatureId classFeatureId = ApplicationFeatureId.newClass(logicalTypeName);
 
         // add class to our map
         // (later on it may get removed if the class turns out to have no features,
@@ -335,41 +355,6 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
         return excluded;
     }
 
-//XXX[2286] .. replaced by check 'spec.getBeanSort().isUnknown()'
-//    /**
-//     * Ignore the (strict) super-classes of any services.
-//     * <p>
-//     * For example, we want to ignore <code>ExceptionRecognizerComposite</code>
-//     * because there is no service of that type (only of subtypes of that).
-//     * </p>
-//     */
-//    private boolean isSuperClassOfService(final ObjectSpecification spec) {
-//
-//        val specClass = spec.getCorrespondingClass();
-//
-//        // is this class a supertype or the actual type of one of the services?
-//        boolean serviceCls = false;
-//        for (final ManagedBeanAdapter bean : registeredServices.get()) {
-//            final Class<?> serviceClass = bean.getBeanClass();
-//            if (specClass.isAssignableFrom(serviceClass)) {
-//                serviceCls = true;
-//            }
-//        }
-//        if (!serviceCls) {
-//            return false;
-//        }
-//
-//        // yes it is.  In which case, is it the actual concrete class of one of those services?
-//        for (final Object registeredService : registeredServices.get()) {
-//            final Class<?> serviceClass = registeredService.getClass();
-//            if (serviceClass.isAssignableFrom(specClass)) {
-//                return false;
-//            }
-//        }
-//        // couldn't find a service of exactly this type, so ignore the spec.
-//        return true;
-//    }
-
     protected boolean isHidden(final ObjectSpecification spec) {
         final HiddenFacet facet = spec.getFacet(HiddenFacet.class);
         return facet != null &&
@@ -472,6 +457,12 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
         return actionFeatures.values();
     }
 
+    @Override
+    public Map<String, ApplicationFeatureId> getFeatureIdentifiersByName() {
+        initializeIfRequired();
+        return featureIdentifiersByName;
+    }
+    
     // -- packageNames, packageNamesContainingClasses, classNamesContainedIn, memberNamesOf
     
     @Override
@@ -503,7 +494,7 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
         }
         final SortedSet<ApplicationFeatureId> contents = pkg.getContents();
         return contents.stream()
-                .filter(ApplicationFeatureId.Predicates.isClassContaining(memberType, this))
+                .filter(_Predicates.isClassContaining(memberType, this))
                 .map(ApplicationFeatureId.Functions.GET_CLASS_NAME)
                 .collect(_Sets.toUnmodifiableSorted());
     }
@@ -518,7 +509,7 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
         }
         final Set<ApplicationFeatureId> classIds = this.classFeatures.keySet();
         return classIds.stream()
-                .filter(ApplicationFeatureId.Predicates.isClassRecursivelyWithin(packageId))
+                .filter(_Predicates.isClassRecursivelyWithin(packageId))
                 .map(ApplicationFeatureId.Functions.GET_CLASS_NAME)
                 .collect(_Sets.toUnmodifiableSorted());
     }
@@ -539,6 +530,6 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
                 .map(ApplicationFeatureId.Functions.GET_MEMBER_NAME)
                 .collect(_Sets.toUnmodifiableSorted());
     }
-
+    
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Asserts.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Asserts.java
new file mode 100644
index 0000000..369d8f7
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Asserts.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.services.appfeat;
+
+import java.util.function.Predicate;
+
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
+
+final class _Asserts {
+
+    public static Predicate<ApplicationFeatureId> isClassContaining(
+            final ApplicationMemberType memberType, final ApplicationFeatureRepositoryDefault applicationFeatures) {
+        return new Predicate<ApplicationFeatureId>() {
+            @Override
+            public boolean test(final ApplicationFeatureId input) {
+                if(input.getType() != ApplicationFeatureType.CLASS) {
+                    return false;
+                }
+                final ApplicationFeature feature = applicationFeatures.findFeature(input);
+                if(feature == null) {
+                    return false;
+                }
+                return memberType == null || !feature.membersOf(memberType).isEmpty();
+            }
+        };
+    }
+
+    public static Predicate<ApplicationFeatureId> isClassRecursivelyWithin(final ApplicationFeatureId packageId) {
+        return (ApplicationFeatureId input) -> input.getParentIds().contains(packageId);
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java
new file mode 100644
index 0000000..93b4fc7
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.services.appfeat;
+
+import java.util.function.Predicate;
+
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
+
+final class _Predicates {
+
+    public static Predicate<ApplicationFeatureId> isClassContaining(
+            final ApplicationMemberType memberType, final ApplicationFeatureRepositoryDefault applicationFeatures) {
+        return new Predicate<ApplicationFeatureId>() {
+            @Override
+            public boolean test(final ApplicationFeatureId input) {
+                if(input.getType() != ApplicationFeatureType.CLASS) {
+                    return false;
+                }
+                final ApplicationFeature feature = applicationFeatures.findFeature(input);
+                if(feature == null) {
+                    return false;
+                }
+                return memberType == null || !feature.membersOf(memberType).isEmpty();
+            }
+        };
+    }
+
+    public static Predicate<ApplicationFeatureId> isClassRecursivelyWithin(final ApplicationFeatureId packageId) {
+        return (ApplicationFeatureId input) -> input.getParentIds().contains(packageId);
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index df26aa9..2969b3a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@ -31,6 +31,8 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
 import org.apache.isis.applib.services.grid.GridService;
@@ -43,8 +45,6 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.facets.members.publish.command.CommandPublishingFacet;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
index 81d201e..2026089 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -39,6 +39,7 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.collections.Can;
@@ -60,7 +61,6 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelService;
 import org.apache.isis.core.metamodel.progmodels.dflt.ProgrammingModelFacetsJava8;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor.Substitution;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorDefault;
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java
index 9f91565..7c319c4 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java
@@ -38,6 +38,8 @@ import static org.hamcrest.Matchers.emptyCollectionOf;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.lessThan;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.internaltestsupport.contract.ValueTypeContractTestAbstract;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
@@ -615,7 +617,7 @@ public class ApplicationFeatureIdTest {
             public void whenNull() throws Exception {
                 expectedException.expect(NullPointerException.class);
 
-                ApplicationFeatureId.Predicates.
+                _Predicates.
                 isClassContaining(ApplicationMemberType.ACTION, mockApplicationFeatureRepository).
                 test(null);
             }
@@ -623,12 +625,12 @@ public class ApplicationFeatureIdTest {
             @Test
             public void whenNotClass() throws Exception {
                 assertThat(
-                        ApplicationFeatureId.Predicates.
+                        _Predicates.
                         isClassContaining(ApplicationMemberType.ACTION, mockApplicationFeatureRepository).
                         test(ApplicationFeatureId.newPackage("com.mycompany")),
                         is(false));
                 assertThat(
-                        ApplicationFeatureId.Predicates.
+                        _Predicates.
                         isClassContaining(ApplicationMemberType.ACTION, mockApplicationFeatureRepository).
                         test(ApplicationFeatureId.newMember("com.mycompany.Bar#foo")),
                         is(false));
@@ -643,7 +645,7 @@ public class ApplicationFeatureIdTest {
                 }});
 
                 assertThat(
-                        ApplicationFeatureId.Predicates.
+                        _Predicates.
                         isClassContaining(ApplicationMemberType.ACTION, mockApplicationFeatureRepository).
                         test(classFeature),
                         is(false));
@@ -660,7 +662,7 @@ public class ApplicationFeatureIdTest {
                 }});
 
                 assertThat(
-                        ApplicationFeatureId.Predicates.
+                        _Predicates.
                         isClassContaining(ApplicationMemberType.ACTION, mockApplicationFeatureRepository).
                         test(classFeature),
                         is(false));
@@ -679,7 +681,7 @@ public class ApplicationFeatureIdTest {
                 }});
 
                 assertThat(
-                        ApplicationFeatureId.Predicates.
+                        _Predicates.
                         isClassContaining(ApplicationMemberType.ACTION, mockApplicationFeatureRepository).
                         test(classFeature),
                         is(true));
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java
index 4e2b515..9f0dd47 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java
@@ -39,6 +39,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
 
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.collections.Can;
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTest.java
index fe47c9e..34c1f79 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTest.java
@@ -27,6 +27,7 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsInAnyOrder;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 
 public class ApplicationFeatureTest {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTypeTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTypeTest.java
index 7398248..3ddb220 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTypeTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureTypeTest.java
@@ -26,6 +26,11 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
+
+import lombok.val;
+
 public class ApplicationFeatureTypeTest {
 
     public static class HideClassName extends ApplicationFeatureTypeTest {
@@ -55,9 +60,7 @@ public class ApplicationFeatureTypeTest {
         @Test
         public void givenPackage() throws Exception {
 
-            final ApplicationFeatureId applicationFeatureId = new ApplicationFeatureId(ApplicationFeatureType.PACKAGE);
-
-            ApplicationFeatureType.PACKAGE.init(applicationFeatureId, "com.mycompany");
+            val applicationFeatureId = ApplicationFeatureId.createPackage("com.mycompany"); 
 
             assertThat(applicationFeatureId.getNamespace(), is("com.mycompany"));
             assertThat(applicationFeatureId.getTypeSimpleName(), is(nullValue()));
@@ -67,9 +70,7 @@ public class ApplicationFeatureTypeTest {
         @Test
         public void givenClass() throws Exception {
 
-            final ApplicationFeatureId applicationFeatureId = new ApplicationFeatureId(ApplicationFeatureType.CLASS);
-
-            ApplicationFeatureType.CLASS.init(applicationFeatureId, "com.mycompany.Bar");
+            val applicationFeatureId = ApplicationFeatureId.createClass("com.mycompany.Bar");
 
             assertThat(applicationFeatureId.getNamespace(), is("com.mycompany"));
             assertThat(applicationFeatureId.getTypeSimpleName(), is("Bar"));
@@ -79,10 +80,8 @@ public class ApplicationFeatureTypeTest {
         @Test
         public void givenMember() throws Exception {
 
-            final ApplicationFeatureId applicationFeatureId = new ApplicationFeatureId(ApplicationFeatureType.MEMBER);
-
-            ApplicationFeatureType.MEMBER.init(applicationFeatureId, "com.mycompany.Bar#foo");
-
+            val applicationFeatureId = ApplicationFeatureId.createMember("com.mycompany.Bar#foo");
+            
             assertThat(applicationFeatureId.getNamespace(), is("com.mycompany"));
             assertThat(applicationFeatureId.getTypeSimpleName(), is("Bar"));
             assertThat(applicationFeatureId.getMemberName(), is("foo"));
@@ -91,9 +90,8 @@ public class ApplicationFeatureTypeTest {
         public void givenMemberMalformed() throws Exception {
 
             expectedException.expect(IllegalArgumentException.class);
-            final ApplicationFeatureId applicationFeatureId = new ApplicationFeatureId(ApplicationFeatureType.MEMBER);
-
-            ApplicationFeatureType.MEMBER.init(applicationFeatureId, "com.mycompany.BarISMISSINGTHEHASHSYMBOL");
+            ApplicationFeatureId
+                    .createMember("com.mycompany.BarISMISSINGTHEHASHSYMBOL");
         }
     }
 
@@ -104,17 +102,17 @@ public class ApplicationFeatureTypeTest {
 
         @Test
         public void whenPackage() throws Exception {
-            ApplicationFeatureType.ensurePackage(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE));
+            ApplicationFeatureType.ensurePackage(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE, "xxx"));
         }
         @Test
         public void whenClass() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensurePackage(new ApplicationFeatureId(ApplicationFeatureType.CLASS));
+            ApplicationFeatureType.ensurePackage(new ApplicationFeatureId(ApplicationFeatureType.CLASS, "xxx"));
         }
         @Test
         public void whenMember() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensurePackage(new ApplicationFeatureId(ApplicationFeatureType.MEMBER));
+            ApplicationFeatureType.ensurePackage(new ApplicationFeatureId(ApplicationFeatureType.MEMBER, "xxx#x"));
         }
     }
 
@@ -125,16 +123,16 @@ public class ApplicationFeatureTypeTest {
 
         @Test
         public void whenPackage() throws Exception {
-            ApplicationFeatureType.ensurePackageOrClass(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE));
+            ApplicationFeatureType.ensurePackageOrClass(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE, "xxx"));
         }
         @Test
         public void whenClass() throws Exception {
-            ApplicationFeatureType.ensurePackageOrClass(new ApplicationFeatureId(ApplicationFeatureType.CLASS));
+            ApplicationFeatureType.ensurePackageOrClass(new ApplicationFeatureId(ApplicationFeatureType.CLASS, "xxx"));
         }
         @Test
         public void whenMember() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensurePackageOrClass(new ApplicationFeatureId(ApplicationFeatureType.MEMBER));
+            ApplicationFeatureType.ensurePackageOrClass(new ApplicationFeatureId(ApplicationFeatureType.MEMBER, "xxx#x"));
         }
 
     }
@@ -146,16 +144,16 @@ public class ApplicationFeatureTypeTest {
         @Test
         public void whenPackage() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensureClass(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE));
+            ApplicationFeatureType.ensureClass(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE, "xxx"));
         }
         @Test
         public void whenClass() throws Exception {
-            ApplicationFeatureType.ensureClass(new ApplicationFeatureId(ApplicationFeatureType.CLASS));
+            ApplicationFeatureType.ensureClass(new ApplicationFeatureId(ApplicationFeatureType.CLASS, "xxx"));
         }
         @Test
         public void whenMember() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensureClass(new ApplicationFeatureId(ApplicationFeatureType.MEMBER));
+            ApplicationFeatureType.ensureClass(new ApplicationFeatureId(ApplicationFeatureType.MEMBER, "xxx#x"));
         }
 
     }
@@ -167,16 +165,16 @@ public class ApplicationFeatureTypeTest {
         @Test
         public void whenPackage() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensureMember(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE));
+            ApplicationFeatureType.ensureMember(new ApplicationFeatureId(ApplicationFeatureType.PACKAGE, "xxx"));
         }
         @Test
         public void whenClass() throws Exception {
             expectedException.expect(IllegalStateException.class);
-            ApplicationFeatureType.ensureMember(new ApplicationFeatureId(ApplicationFeatureType.CLASS));
+            ApplicationFeatureType.ensureMember(new ApplicationFeatureId(ApplicationFeatureType.CLASS, "xxx"));
         }
         @Test
         public void whenMember() throws Exception {
-            ApplicationFeatureType.ensureMember(new ApplicationFeatureId(ApplicationFeatureType.MEMBER));
+            ApplicationFeatureType.ensureMember(new ApplicationFeatureId(ApplicationFeatureType.MEMBER, "xxx#x"));
         }
     }
 
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 dc3188a..f49b996 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
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.security.authentication.Authentication;
 import org.apache.isis.core.security.authorization.Authorizor;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
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 0a7b6d0..1c423aa 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
@@ -26,10 +26,10 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 
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 eb7c476..8af8ea8 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
@@ -21,8 +21,8 @@ package org.apache.isis.extensions.secman.api.permission;
 import java.util.Collection;
 import java.util.Optional;
 
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 
 /**
@@ -62,11 +62,17 @@ public interface ApplicationPermissionRepository<P extends ApplicationPermission
             String memberName);
 
     P newPermission(
-            ApplicationRole holder,
+            ApplicationRole role,
             ApplicationPermissionRule rule,
             ApplicationPermissionMode mode,
             ApplicationFeatureType featureType,
             String featureFqn);
 
-
+    P 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/ApplicationPermissionValue.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java
index fbd3766..6bd68ab 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java
@@ -23,9 +23,9 @@ import java.util.Comparator;
 import java.util.List;
 
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ToString;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 
 /**
  * A serializable value object representing an (anonymized)
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java
index 5c53ecc..fadcaa1 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java
@@ -24,10 +24,10 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 
 /**
  * A serializable value object representing a set of (anonymized)
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationService.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationService.java
index dfef149..25cc3da 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationService.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationService.java
@@ -21,7 +21,7 @@ package org.apache.isis.extensions.secman.api.permission;
 import java.io.Serializable;
 import java.util.Collection;
 
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 
 /**
  * Strategy for determining which permission should apply when there are multiple that apply for a particular target
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationServiceAbstract.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationServiceAbstract.java
index 3c041ac..ed76f82 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationServiceAbstract.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/PermissionsEvaluationServiceAbstract.java
@@ -20,8 +20,8 @@ package org.apache.isis.extensions.secman.api.permission;
 
 import java.util.Collection;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 
 /**
  * @since 2.0 {@index}
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 1fa9dd0..7a17ceb 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
@@ -37,11 +37,8 @@ public interface ApplicationRole {
 
     public static class AddUserDomainEvent extends ActionDomainEvent {}
     public static class RemoveUserDomainEvent extends ActionDomainEvent {}
-    public static class AddActionDomainEvent extends ActionDomainEvent {}
-    public static class AddClassDomainEvent extends ActionDomainEvent {}
-    public static class AddCollectionDomainEvent extends ActionDomainEvent {}
-    public static class AddPackageDomainEvent extends ActionDomainEvent {}
-    public static class AddPropertyDomainEvent extends ActionDomainEvent {}
+    
+    public static class AddPermissionDomainEvent extends ActionDomainEvent {}
     public static class RemovePermissionDomainEvent extends ActionDomainEvent {}
 
     public static class DeleteDomainEvent extends ActionDomainEvent {}
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClass.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClass.java
index 3025871..6758fd1 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClass.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClass.java
@@ -27,7 +27,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.MemberOrder;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 
 @DomainObject(
         objectType = "isis.ext.secman.ApplicationClass"
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassAction.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassAction.java
index 4e0786c..8240238 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassAction.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassAction.java
@@ -23,7 +23,7 @@ import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 
 @DomainObject(
         objectType = "isis.ext.secman.ApplicationClassAction"
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassCollection.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassCollection.java
index eddfe64..c1a1cad 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassCollection.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassCollection.java
@@ -22,7 +22,7 @@ import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 
 @DomainObject(
         objectType = "isis.ext.secman.ApplicationClassCollection"
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassMember.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassMember.java
index 12294b9..3b3ad36 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassMember.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassMember.java
@@ -23,7 +23,7 @@ import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 
 @DomainObject(
         objectType = "isis.ext.secman.ApplicationClassMember"
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassProperty.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassProperty.java
index e59a407..e4c5bf9 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassProperty.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationClassProperty.java
@@ -23,7 +23,7 @@ import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 
 @DomainObject(
         objectType = "isis.ext.secman.ApplicationClassProperty"
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java
index 463f638..f7991c5 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java
@@ -33,6 +33,8 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
@@ -41,9 +43,7 @@ import org.apache.isis.applib.util.ToString;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 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.ApplicationPermissionRepository;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPackage.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPackage.java
index 7ca2deb..88a6cdd 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPackage.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPackage.java
@@ -26,8 +26,8 @@ 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.MemberOrder;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 
 @DomainObject(
         objectType = "isis.ext.secman.ApplicationPackage"
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPermission_feature.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPermission_feature.java
index 72aae4e..21ae587 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPermission_feature.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationPermission_feature.java
@@ -24,9 +24,9 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java
index 6e07945..b8b1c7b 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java
@@ -31,10 +31,10 @@ import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 
@@ -52,7 +52,7 @@ public class ApplicationUser_filterPermissions {
     @Inject private FactoryService factory;
     @Inject private ApplicationFeatureRepositoryDefault applicationFeatureRepository;
 
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public List<UserPermissionViewModel> act(
@@ -103,7 +103,7 @@ public class ApplicationUser_filterPermissions {
     List<UserPermissionViewModel> asViewModels(final Collection<ApplicationFeature> features) {
         return _Lists.map(
                 features,
-                UserPermissionViewModel.Functions.asViewModel(holder, factory));
+                UserPermissionViewModel.Functions.asViewModel(target, factory));
     }
 
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_permissions.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_permissions.java
index 64c4455..f357af5 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_permissions.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_permissions.java
@@ -51,7 +51,7 @@ public class ApplicationUser_permissions {
     @Inject private FactoryService factory;
     @Inject private ApplicationFeatureRepositoryDefault applicationFeatureRepository;
 
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public List<UserPermissionViewModel> coll() {
@@ -62,7 +62,7 @@ public class ApplicationUser_permissions {
     List<UserPermissionViewModel> asViewModels(final java.util.Collection<ApplicationFeature> features) {
         return _Lists.map(
                 features,
-                UserPermissionViewModel.Functions.asViewModel(holder, factory));
+                UserPermissionViewModel.Functions.asViewModel(target, factory));
     }
 
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java
index 89c4472..38296f8 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java
@@ -37,15 +37,15 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ToString;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
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 f3ab4a7..7af6069 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
@@ -22,7 +22,6 @@ import java.util.Collection;
 
 import javax.inject.Inject;
 
-import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
@@ -45,9 +44,9 @@ public class ApplicationOrphanedPermissionManager {
         return applicationPermissionRepository.findOrphaned();
     }
     
-    @Action
-    public Collection<? extends ApplicationPermission> debugOrphanedPermissions() {
-        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/ApplicationOrphanedPermissionManager_relocateSelected.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java
index 76dc2a5..b168e67 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationOrphanedPermissionManager_relocateSelected.java
@@ -26,7 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission.RelocateNamespaceDomainEvent;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java
index 05f7213..c3fb67b 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_allow.java
@@ -29,16 +29,16 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationPermission_allow {
 
-    private final ApplicationPermission holder;
+    private final ApplicationPermission target;
 
     //@MemberOrder(name = "Rule", sequence = "1")
     public ApplicationPermission act() {
-        holder.setRule(ApplicationPermissionRule.ALLOW);
-        return holder;
+        target.setRule(ApplicationPermissionRule.ALLOW);
+        return target;
     }
 
     public String disableAct() {
-        return holder.getRule() == ApplicationPermissionRule.ALLOW? "Rule is already set to ALLOW": null;
+        return target.getRule() == ApplicationPermissionRule.ALLOW? "Rule is already set to ALLOW": null;
     }
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java
index f4c2f3c..621ee0f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_changing.java
@@ -29,16 +29,16 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationPermission_changing {
 
-    private final ApplicationPermission holder;
+    private final ApplicationPermission target;
 
     //@MemberOrder(name = "Mode", sequence = "2")
     public ApplicationPermission act() {
-        holder.setMode(ApplicationPermissionMode.CHANGING);
-        return holder;
+        target.setMode(ApplicationPermissionMode.CHANGING);
+        return target;
     }
     
     public String disableAct() {
-        return holder.getMode() == ApplicationPermissionMode.CHANGING ? "Mode is already set to CHANGING": null;
+        return target.getMode() == ApplicationPermissionMode.CHANGING ? "Mode is already set to CHANGING": null;
     }
     
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java
index 0f7194c..8ffda8a 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_delete.java
@@ -30,17 +30,19 @@ import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-@Action(domainEvent = DeleteDomainEvent.class, semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
+@Action(
+        domainEvent = DeleteDomainEvent.class, 
+        semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE)
 @RequiredArgsConstructor
 public class ApplicationPermission_delete {
     
     @Inject private RepositoryService repository;
 
-    private final ApplicationPermission holder;
+    private final ApplicationPermission target;
 
     public ApplicationRole act() {
-        val owningRole = holder.getRole();
-        repository.remove(holder);
+        val owningRole = target.getRole();
+        repository.remove(target);
         return owningRole;
     }
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_updateRole.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_updateRole.java
index da3c3e1..9e3d4f0 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
@@ -31,23 +31,25 @@ import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = UpdateRoleDomainEvent.class, associateWith = "role")
+@Action(
+        domainEvent = UpdateRoleDomainEvent.class, 
+        associateWith = "role")
 @RequiredArgsConstructor
 public class ApplicationPermission_updateRole {
 
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     
-    private final ApplicationPermission holder;
+    private final ApplicationPermission target;
     
     @Model
     public ApplicationPermission act(final ApplicationRole applicationRole) {
-        holder.setRole(applicationRole);
-        return holder;
+        target.setRole(applicationRole);
+        return target;
     }
 
     @Model
     public ApplicationRole default0Act() {
-        return holder.getRole();
+        return target.getRole();
     }
 
     @Model
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java
index 0d5ee2e..1e97cb9 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_veto.java
@@ -25,19 +25,21 @@ import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRul
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = VetoDomainEvent.class, associateWith = "rule")
+@Action(
+        domainEvent = VetoDomainEvent.class, 
+        associateWith = "rule")
 @RequiredArgsConstructor
 public class ApplicationPermission_veto {
 
-    private final ApplicationPermission holder;
+    private final ApplicationPermission target;
 
     //@MemberOrder(name = "Rule", sequence = "1")
     public ApplicationPermission act() {
-        holder.setRule(ApplicationPermissionRule.VETO);
-        return holder;
+        target.setRule(ApplicationPermissionRule.VETO);
+        return target;
     }
     public String disableAct() {
-        return holder.getRule() == ApplicationPermissionRule.VETO? "Rule is already set to VETO": null;
+        return target.getRule() == ApplicationPermissionRule.VETO? "Rule is already set to VETO": null;
     }
     
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java
index 98e96e3..f3af1e5 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermission_viewing.java
@@ -25,20 +25,22 @@ import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMod
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = ViewingDomainEvent.class, associateWith = "mode")
+@Action(
+        domainEvent = ViewingDomainEvent.class, 
+        associateWith = "mode")
 @RequiredArgsConstructor
 public class ApplicationPermission_viewing {
 
-    private final ApplicationPermission holder;
+    private final ApplicationPermission target;
     
     //@MemberOrder(name = "Mode", sequence = "1")
     public ApplicationPermission act() {
-        holder.setMode(ApplicationPermissionMode.VIEWING);
-        return holder;
+        target.setMode(ApplicationPermissionMode.VIEWING);
+        return target;
     }
     
     public String disableAct() {
-        return holder.getMode() == ApplicationPermissionMode.VIEWING ? "Mode is already set to VIEWING": null;
+        return target.getMode() == ApplicationPermissionMode.VIEWING ? "Mode is already set to VIEWING": null;
     }
     
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
index ef977c7..c084589 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
@@ -25,19 +25,21 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddActionDomainEvent;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = AddActionDomainEvent.class, associateWith = "permissions")
+@Action(
+        domainEvent = AddPermissionDomainEvent.class, 
+        associateWith = "permissions")
 @RequiredArgsConstructor
 public class ApplicationRole_addAction {
     
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java
index db47ff7..aa3a2a9 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java
@@ -24,18 +24,20 @@ import javax.inject.Inject;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddClassDomainEvent;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = AddClassDomainEvent.class, associateWith = "permissions")
+@Action(
+        domainEvent = AddPermissionDomainEvent.class, 
+        associateWith = "permissions")
 @RequiredArgsConstructor
 public class ApplicationRole_addClass {
     
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java
index c64442b..d83db09 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java
@@ -27,19 +27,21 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddCollectionDomainEvent;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = AddCollectionDomainEvent.class, associateWith = "permissions")
+@Action(
+        domainEvent = AddPermissionDomainEvent.class, 
+        associateWith = "permissions")
 @RequiredArgsConstructor
 public class ApplicationRole_addCollection {
     
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java
index 29c360d..4b2994c 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java
@@ -25,18 +25,20 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPackageDomainEvent;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = AddPackageDomainEvent.class, associateWith = "permissions")
+@Action(
+        domainEvent = AddPermissionDomainEvent.class, 
+        associateWith = "permissions")
 @RequiredArgsConstructor
 public class ApplicationRole_addPackage {
     
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java
similarity index 52%
copy from extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
copy to extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java
index ef977c7..d5293ee 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPermission.java
@@ -18,87 +18,108 @@
  */
 package org.apache.isis.extensions.secman.model.dom.role;
 
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
 import javax.enterprise.inject.Model;
 import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.MinLength;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
-import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddActionDomainEvent;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
+import lombok.Value;
+import lombok.val;
+import lombok.experimental.Accessors;
 
-@Action(domainEvent = AddActionDomainEvent.class, associateWith = "permissions")
+//TODO[2560] wip
+//@Action(
+//        domainEvent = AddPermissionDomainEvent.class, 
+//        associateWith = "permissions")
+//@ActionLayout(promptStyle = PromptStyle.DIALOG_MODAL)
 @RequiredArgsConstructor
-public class ApplicationRole_addAction {
+public class ApplicationRole_addPermission {
     
     @Inject private ApplicationFeatureRepository applicationFeatureRepository;
     @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
+    
+    @Value @Accessors(fluent = true)           
+    public static class Parameters {
+        ApplicationPermissionRule rule; // ALLOW/VETO
+        ApplicationPermissionMode mode; // r/w
+        String feature;
+    }
 
     /**
      * Adds a {@link ApplicationPermission permission} for this role to a
-     * {@link ApplicationMemberType#ACTION action}
-     * {@link ApplicationFeatureType#MEMBER member}
      * {@link ApplicationFeature feature}.
      */
     @MemberOrder(sequence = "3")
     public ApplicationRole act(
+            
+            @Parameter(optionality = Optionality.MANDATORY)
             @ParameterLayout(named="Rule")
             final ApplicationPermissionRule rule,
+            
+            @Parameter(optionality = Optionality.MANDATORY)
             @ParameterLayout(named="Mode")
             final ApplicationPermissionMode mode,
-            @ParameterLayout(named="Package", typicalLength=ApplicationFeature.TYPICAL_LENGTH_PKG_FQN)
-            final String packageFqn,
-            @ParameterLayout(named="Class", typicalLength=ApplicationFeature.TYPICAL_LENGTH_CLS_NAME)
-            final String className,
-            @ParameterLayout(named="Action", typicalLength = ApplicationFeature.TYPICAL_LENGTH_MEMBER_NAME)
-            final String memberName) {
+            
+            @Parameter(optionality = Optionality.MANDATORY)
+            @ParameterLayout(named="Feature")
+            final String featureName) {
+        
+        val featureId = ApplicationFeatureId.parse(featureName);
         
-        applicationPermissionRepository.newPermission(holder, rule, mode, packageFqn, className, memberName);
-        return holder;
+        applicationPermissionRepository.newPermission(target, rule, mode, featureId);
+        return target;
     }
 
     @Model
-    public ApplicationPermissionRule default0Act() {
+    public ApplicationPermissionRule defaultRule(Parameters params) {
         return ApplicationPermissionRule.ALLOW;
     }
 
     @Model
-    public ApplicationPermissionMode default1Act() {
+    public ApplicationPermissionMode defaultMode(Parameters params) {
         return ApplicationPermissionMode.CHANGING;
     }
 
     @Model
-    public java.util.Collection<String> choices2Act() {
-        return applicationFeatureRepository.packageNamesContainingClasses(ApplicationMemberType.ACTION);
+    public java.util.Collection<String> autoComplete2Act(             
+            @MinLength(3) String search) {
+        
+        val idsByName = applicationFeatureRepository.getFeatureIdentifiersByName();
+        
+        return idsByName.entrySet().stream()
+        .filter(entry->matches(entry.getKey(), entry.getValue(), search))
+        .map(Map.Entry::getValue)
+        .map(ApplicationFeatureId::asString)
+        .collect(Collectors.toCollection(TreeSet::new));
     }
 
-    @Model
-    public java.util.Collection<String> choices3Act(
-            final ApplicationPermissionRule rule,
-            final ApplicationPermissionMode mode,
-            final String packageFqn) {
-        return applicationFeatureRepository.classNamesContainedIn(packageFqn, ApplicationMemberType.ACTION);
+    private boolean matches(String featureName, ApplicationFeatureId featureId, String search) {
+        //TODO yet not very smart
+        return featureName.contains(search);
     }
 
-    @Model
-    public java.util.Collection<String> choices4Act(
-            final ApplicationPermissionRule rule,
-            final ApplicationPermissionMode mode,
-            final String packageFqn,
-            final String className) {
-        return applicationFeatureRepository.memberNamesOf(packageFqn, className, ApplicationMemberType.ACTION);
-    }
     
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java
index 131cbbb..7da2f1e 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java
@@ -27,19 +27,21 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPropertyDomainEvent;
+import org.apache.isis.extensions.secman.api.role.ApplicationRole.AddPermissionDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = AddPropertyDomainEvent.class, associateWith = "permissions")
+@Action(
+        domainEvent = AddPermissionDomainEvent.class, 
+        associateWith = "permissions")
 @RequiredArgsConstructor
 public class ApplicationRole_addProperty {
     
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 4eebbf3..2301c4e 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
@@ -46,19 +46,19 @@ public class ApplicationRole_addUser {
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
 
     @Model
     public ApplicationRole act(final ApplicationUser applicationUser) {
-        applicationRoleRepository.addRoleToUser(holder, applicationUser);
-        return holder;
+        applicationRoleRepository.addRoleToUser(target, applicationUser);
+        return target;
     }
 
     @Model
     public List<? extends ApplicationUser> autoComplete0Act(final String search) {
         final Collection<? extends ApplicationUser> matchingSearch = applicationUserRepository.find(search);
         final List<? extends ApplicationUser> list = _Lists.newArrayList(matchingSearch);
-        list.removeAll(applicationUserRepository.findByRole(holder));
+        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_removePermission.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java
index e5a27b2..a0093b8 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java
@@ -24,10 +24,10 @@ import javax.enterprise.inject.Model;
 import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
@@ -51,7 +51,7 @@ public class ApplicationRole_removePermission {
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
 
     @Model
     public ApplicationRole act(
@@ -63,12 +63,12 @@ public class ApplicationRole_removePermission {
             final String featureFqn) {
         
         final ApplicationPermission permission = applicationPermissionRepository
-                .findByRoleAndRuleAndFeature(holder, rule, type, featureFqn)
+                .findByRoleAndRuleAndFeature(target, rule, type, featureFqn)
                 .orElse(null);
         if(permission != null) {
             repository.remove(permission);
         }
-        return holder;
+        return target;
     }
 
     @Model
@@ -79,7 +79,7 @@ public class ApplicationRole_removePermission {
             final ApplicationFeatureType type,
             @ParameterLayout(named="Feature", typicalLength=ApplicationFeature.TYPICAL_LENGTH_MEMBER_NAME)
             final String featureFqn) {
-        if(applicationRoleRepository.isAdminRole(holder) 
+        if(applicationRoleRepository.isAdminRole(target) 
                 && configBean.isStickyAdminNamespace(featureFqn)) {
             return "Cannot remove top-level namespace permissions for the admin role.";
         }
@@ -102,7 +102,7 @@ public class ApplicationRole_removePermission {
             final ApplicationFeatureType type) {
         
         final Collection<? extends ApplicationPermission> permissions = applicationPermissionRepository
-                .findByRoleAndRuleAndFeatureTypeCached(holder, rule, type);
+                .findByRoleAndRuleAndFeatureTypeCached(target, rule, type);
         return _Lists.map(
                 permissions,
                 ApplicationPermission::getFeatureFqn);
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 82d3da1..9188f36 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
@@ -51,7 +51,7 @@ public class ApplicationRole_removePermissions {
     @Inject private RepositoryService repository;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
 
     @Model
     public ApplicationRole act(Collection<ApplicationPermission> permissions) {
@@ -60,14 +60,14 @@ public class ApplicationRole_removePermissions {
         .filter(this::canRemove)
         .forEach(repository::remove);
         
-        return holder;
+        return target;
     }
 
     private boolean canRemove(ApplicationPermission permission) {
-        if(!Objects.equals(permission.getRole(), holder)) {
+        if(!Objects.equals(permission.getRole(), target)) {
             return false;
         }
-        if(applicationRoleRepository.isAdminRole(holder) 
+        if(applicationRoleRepository.isAdminRole(target) 
                 && configBean.isStickyAdminNamespace(permission.getFeatureFqn())) {
             
             messageService.warnUser("Cannot remove top-level namespace permissions for the admin role.");
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUser.java
index 4720c3c..9d8f9c7 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removeUser.java
@@ -42,23 +42,23 @@ public class ApplicationRole_removeUser {
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
 
     @Model
     public ApplicationRole act(final ApplicationUser applicationUser) {
-        applicationRoleRepository.removeRoleFromUser(holder, applicationUser);
-        return holder;
+        applicationRoleRepository.removeRoleFromUser(target, applicationUser);
+        return target;
     }
 
     @Model
     public Collection<? extends ApplicationUser> choices0Act() {
-        return applicationUserRepository.findByRole(holder);
+        return applicationUserRepository.findByRole(target);
     }
 
     @Model
     public String validateAct(final ApplicationUser applicationUser) {
         if(applicationUserRepository.isAdminUser(applicationUser) 
-                && applicationRoleRepository.isAdminRole(holder)) {
+                && applicationRoleRepository.isAdminRole(target)) {
             return "Cannot remove admin user from the admin role.";
         }
         return null;
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 90e991c..4d0773b 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
@@ -47,21 +47,21 @@ public class ApplicationRole_removeUsers {
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
 
     @Model
     public ApplicationRole act(Collection<ApplicationUser> users) {
         
         _NullSafe.stream(users)
         .filter(this::canRemove)
-        .forEach(user->applicationRoleRepository.removeRoleFromUser(holder, user));
+        .forEach(user->applicationRoleRepository.removeRoleFromUser(target, user));
 
-        return holder;
+        return target;
     }
     
     public boolean canRemove(ApplicationUser applicationUser) {
         if(applicationUserRepository.isAdminUser(applicationUser) 
-                && applicationRoleRepository.isAdminRole(holder)) {
+                && applicationRoleRepository.isAdminRole(target)) {
             messageService.warnUser("Cannot remove admin user from the admin role.");
             return false;
         }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java
index d748d1c..4b8fdd6 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateDescription.java
@@ -31,11 +31,13 @@ import org.apache.isis.extensions.secman.api.role.ApplicationRole.UpdateDescript
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = UpdateDescriptionDomainEvent.class, associateWith = "description")
+@Action(
+        domainEvent = UpdateDescriptionDomainEvent.class, 
+        associateWith = "description")
 @RequiredArgsConstructor
 public class ApplicationRole_updateDescription {
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
     
     @MemberOrder(sequence = "1")
     public ApplicationRole act(
@@ -48,13 +50,13 @@ public class ApplicationRole_updateDescription {
                     typicalLength=ApplicationRole.TYPICAL_LENGTH_DESCRIPTION)
             final String description) {
         
-        holder.setDescription(description);
-        return holder;
+        target.setDescription(description);
+        return target;
     }
 
     @Model
     public String default0Act() {
-        return holder.getDescription();
+        return target.getDescription();
     }
 
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java
index a8e7614..3d72bc6 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_updateName.java
@@ -27,11 +27,13 @@ import org.apache.isis.extensions.secman.api.role.ApplicationRole.UpdateNameDoma
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = UpdateNameDomainEvent.class, associateWith = "name")
+@Action(
+        domainEvent = UpdateNameDomainEvent.class, 
+        associateWith = "name")
 @RequiredArgsConstructor
 public class ApplicationRole_updateName {
     
-    private final ApplicationRole holder;
+    private final ApplicationRole target;
     
     @MemberOrder(sequence = "1")
     public ApplicationRole updateName(
@@ -39,12 +41,12 @@ public class ApplicationRole_updateName {
             @ParameterLayout(named="Name", typicalLength = ApplicationRole.TYPICAL_LENGTH_NAME)
             final String name) {
         
-        holder.setName(name);
-        return holder;
+        target.setName(name);
+        return target;
     }
 
     public String default0UpdateName() {
-        return holder.getName();
+        return target.getName();
     }
 
 }
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 728e120..b4359b9 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
@@ -37,11 +37,11 @@ public class ApplicationTenancy_addChild {
     
     @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
     
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     @Model
     public ApplicationTenancy act(final ApplicationTenancy child) {
-        applicationTenancyRepository.setParentOnTenancy(child, holder);
-        return holder;
+        applicationTenancyRepository.setParentOnTenancy(child, target);
+        return target;
     }
 }
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 c0c814d..4e8bf7d 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
@@ -46,19 +46,19 @@ public class ApplicationTenancy_addUser {
     @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     @Model
     public ApplicationTenancy act(final ApplicationUser applicationUser) {
-        applicationTenancyRepository.setTenancyOnUser(holder, applicationUser);
-        return holder;
+        applicationTenancyRepository.setTenancyOnUser(target, applicationUser);
+        return target;
     }
 
     @Model
     public List<? extends ApplicationUser> autoComplete0Act(final String search) {
         final Collection<? extends ApplicationUser> matchingSearch = applicationUserRepository.find(search);
         final List<? extends ApplicationUser> list = _Lists.newArrayList(matchingSearch);
-        list.removeAll(applicationUserRepository.findByTenancy(holder));
+        list.removeAll(applicationUserRepository.findByTenancy(target));
         return list;
     }
 }
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 9d6edaf..43d7174 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
@@ -49,12 +49,12 @@ public class ApplicationTenancy_delete {
     @Inject private FactoryService factoryService;
     @Inject private RepositoryService repository;
 
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     
     @Model
     public Collection<? extends ApplicationTenancy> act() {
-        for (val user : applicationUserRepository.findByTenancy(holder)) {
+        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 02bfc24..0c75ec2 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
@@ -30,24 +30,26 @@ import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyRepositor
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = RemoveChildDomainEvent.class, associateWith = "children", 
-associateWithSequence = "2")
+@Action(
+        domainEvent = RemoveChildDomainEvent.class, 
+        associateWith = "children", 
+        associateWithSequence = "2")
 @RequiredArgsConstructor
 public class ApplicationTenancy_removeChild {
     
     @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
 
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     @Model
     public ApplicationTenancy act(final ApplicationTenancy child) {
         applicationTenancyRepository.clearParentOnTenancy(child);
-        return holder;
+        return target;
     }
     
     @Model
     public Collection<? extends ApplicationTenancy> choices0Act() {
-        return applicationTenancyRepository.getChildren(holder);
+        return applicationTenancyRepository.getChildren(target);
     }
     
     @Model
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 5707cae..f19cd38 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
@@ -33,8 +33,10 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = RemoveUserDomainEvent.class, associateWith = "users", 
-associateWithSequence = "2")
+@Action(
+        domainEvent = RemoveUserDomainEvent.class, 
+        associateWith = "users", 
+        associateWithSequence = "2")
 @ActionLayout(named="Remove")
 @RequiredArgsConstructor
 public class ApplicationTenancy_removeUser {
@@ -42,17 +44,17 @@ public class ApplicationTenancy_removeUser {
     @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
     
     @Model
     public ApplicationTenancy act(final ApplicationUser applicationUser) {
         applicationTenancyRepository.clearTenancyOnUser(applicationUser);
-        return holder;
+        return target;
     }
     
     @Model
     public Collection<? extends ApplicationUser> choices0Act() {
-        return applicationUserRepository.findByTenancy(holder);
+        return applicationUserRepository.findByTenancy(target);
     }
     
     @Model
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateName.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateName.java
index 15338e6..da1755c 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateName.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/tenancy/ApplicationTenancy_updateName.java
@@ -28,24 +28,26 @@ import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancy.UpdateNa
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = UpdateNameDomainEvent.class, associateWith = "name", 
-associateWithSequence = "1")
+@Action(
+        domainEvent = UpdateNameDomainEvent.class, 
+        associateWith = "name",
+        associateWithSequence = "1")
 @RequiredArgsConstructor
 public class ApplicationTenancy_updateName {
     
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     @Model
     public ApplicationTenancy act(
             @Parameter(maxLength = ApplicationTenancy.MAX_LENGTH_NAME)
             @ParameterLayout(named="Name", typicalLength=ApplicationTenancy.TYPICAL_LENGTH_NAME)
             final String name) {
-        holder.setName(name);
-        return holder;
+        target.setName(name);
+        return target;
     }
 
     @Model
     public String default0Act() {
-        return holder.getName();
+        return target.getName();
     }
 }
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 011e800..0e17732 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
@@ -39,19 +39,19 @@ public class ApplicationTenancy_updateParent {
     
     @Inject private ApplicationTenancyRepository<? extends ApplicationTenancy> applicationTenancyRepository;
     
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     @Model
     public ApplicationTenancy act(
             @Parameter(optionality = Optionality.OPTIONAL)
             final ApplicationTenancy parent) {
         
-        applicationTenancyRepository.setParentOnTenancy(holder, parent);
-        return holder;
+        applicationTenancyRepository.setParentOnTenancy(target, parent);
+        return target;
     }
 
     @Model
     public ApplicationTenancy default0Act() {
-        return holder.getParent();
+        return target.getParent();
     }
 }
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 e49ef74..f6ee381 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
@@ -39,14 +39,14 @@ public class ApplicationTenancy_users {
     
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationTenancy holder;
+    private final ApplicationTenancy target;
 
     // -- users (collection)
 
     public static class UsersDomainEvent extends CollectionDomainEvent<ApplicationUser> {}
 
     public java.util.Collection<? extends ApplicationUser> coll() {
-        return applicationUserRepository.findByAtPath(holder.getPath());
+        return applicationUserRepository.findByAtPath(target.getPath());
     }
 
 }
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 2ca0d25..604311d 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
@@ -32,7 +32,9 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = NewDelegateUserDomainEvent.class, associateWith = "allUsers")
+@Action(
+        domainEvent = NewDelegateUserDomainEvent.class, 
+        associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newDelegateUser {
     
@@ -41,7 +43,7 @@ public class ApplicationUserManager_newDelegateUser {
     @Inject private RepositoryService repository;
 
     @SuppressWarnings("unused")
-    private final ApplicationUserManager holder;
+    private final ApplicationUserManager target;
     
     @Model
     public ApplicationUser act(
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 995ce0a..de986c7 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
@@ -36,7 +36,9 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
 import lombok.RequiredArgsConstructor;
 
-@Action(domainEvent = NewLocalUserDomainEvent.class, associateWith = "allUsers")
+@Action(
+        domainEvent = NewLocalUserDomainEvent.class, 
+        associateWith = "allUsers")
 @RequiredArgsConstructor
 public class ApplicationUserManager_newLocalUser {
     
@@ -46,7 +48,7 @@ public class ApplicationUserManager_newLocalUser {
     @Inject private RepositoryService repository;
     
     @SuppressWarnings("unused")
-    private final ApplicationUserManager holder;
+    private final ApplicationUserManager target;
 
     @Model
     public ApplicationUser act(
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 cc50625..fbd9217 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
@@ -34,25 +34,27 @@ import org.apache.isis.extensions.secman.api.user.ApplicationUser.AddRoleDomainE
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-@Action(domainEvent = AddRoleDomainEvent.class, associateWith = "roles")
+@Action(
+        domainEvent = AddRoleDomainEvent.class, 
+        associateWith = "roles")
 @ActionLayout(named="Add")
 @RequiredArgsConstructor
 public class ApplicationUser_addRole {
     
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @MemberOrder(sequence = "1")
     public ApplicationUser act(final ApplicationRole role) {
-        applicationRoleRepository.addRoleToUser(role, holder);
-        return holder;
+        applicationRoleRepository.addRoleToUser(role, target);
+        return target;
     }
 
     public Collection<? extends ApplicationRole> choices0Act() {
         val allRoles = applicationRoleRepository.allRoles();
         val applicationRoles = _Sets.newTreeSet(allRoles);
-        applicationRoles.removeAll(holder.getRoles());
+        applicationRoles.removeAll(target.getRoles());
         return applicationRoles;
     }
 
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 b9d10a9..56ca931 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
@@ -42,16 +42,16 @@ public class ApplicationUser_delete {
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private RepositoryService repository;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public Collection<? extends ApplicationUser> act() {
-        repository.removeAndFlush(holder);
+        repository.removeAndFlush(target);
         return applicationUserRepository.allUsers();
     }
 
     @Model
     public String disableAct() {
-        return applicationUserRepository.isAdminUser(holder)? "Cannot delete the admin user": null;
+        return applicationUserRepository.isAdminUser(target)? "Cannot delete the admin user": null;
     }
 }
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 a84659b..841c6f5 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
@@ -42,7 +42,7 @@ public class ApplicationUser_duplicate {
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
 
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
@@ -52,12 +52,12 @@ public class ApplicationUser_duplicate {
             final String emailAddress) {
         
         return applicationUserRepository
-                .newUser(username, holder.getAccountType(), user->{
+                .newUser(username, target.getAccountType(), user->{
         
                     user.setStatus(ApplicationUserStatus.DISABLED);
                     user.setEmailAddress(emailAddress);
         
-                    for (ApplicationRole role : holder.getRoles()) {
+                    for (ApplicationRole role : target.getRoles()) {
                         applicationRoleRepository.addRoleToUser(role, user);
                     }
                     
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_lock.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_lock.java
index 55cd9df..2dcca68 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
@@ -42,19 +42,19 @@ public class ApplicationUser_lock {
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private SecmanConfiguration configBean;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act() {
-        holder.setStatus(ApplicationUserStatus.DISABLED);
-        return holder;
+        target.setStatus(ApplicationUserStatus.DISABLED);
+        return target;
     }
     
     @Model
     public String disableAct() {
-        if(applicationUserRepository.isAdminUser(holder)) {
+        if(applicationUserRepository.isAdminUser(target)) {
             return "Cannot disable the '" + configBean.getAdminUserName() + "' user.";
         }
-        return holder.getStatus() == ApplicationUserStatus.DISABLED ? "Status is already set to DISABLE": null;
+        return target.getStatus() == ApplicationUserStatus.DISABLED ? "Status is already set to DISABLE": null;
     }
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRole.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRole.java
index ee2d78c..a56745d 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRole.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_removeRole.java
@@ -44,29 +44,29 @@ public class ApplicationUser_removeRole {
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(final ApplicationRole role) {
-        applicationRoleRepository.removeRoleFromUser(role, holder);
-        return holder;
+        applicationRoleRepository.removeRoleFromUser(role, target);
+        return target;
     }
 
     @Model
     public String disableAct() {
-        return holder.getRoles().isEmpty()? "No roles to remove": null;
+        return target.getRoles().isEmpty()? "No roles to remove": null;
     }
 
     @Model
     public Collection<? extends ApplicationRole> choices0Act() {
-        return applicationRoleRepository.getRoles(holder);
+        return applicationRoleRepository.getRoles(target);
     }
 
     @Model
     // duplicated in ApplicationRole_removeUser mixin
     public String validateAct(
             final ApplicationRole applicationRole) {
-        if(applicationUserRepository.isAdminUser(holder) 
+        if(applicationUserRepository.isAdminUser(target) 
                 && applicationRoleRepository.isAdminRole(applicationRole)) {
             return "Cannot remove admin user from the admin role.";
         }
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 139ae9c..fb67117 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
@@ -49,7 +49,7 @@ public class ApplicationUser_removeRoles {
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     
     @Model
@@ -57,9 +57,9 @@ public class ApplicationUser_removeRoles {
         
         _NullSafe.stream(roles)
         .filter(this::canRemove)
-        .forEach(role->applicationRoleRepository.removeRoleFromUser(role, holder));
+        .forEach(role->applicationRoleRepository.removeRoleFromUser(role, target));
         
-        return holder;
+        return target;
     }
 
     @Model
@@ -67,7 +67,7 @@ public class ApplicationUser_removeRoles {
     public boolean canRemove(
             final ApplicationRole applicationRole) {
         
-        if(applicationUserRepository.isAdminUser(holder) 
+        if(applicationUserRepository.isAdminUser(target) 
                 && applicationRoleRepository.isAdminRole(applicationRole)) {
             messageService.warnUser("Cannot remove admin user from the admin role.");
             return false;
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 245d37d..588afa3 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
@@ -41,7 +41,7 @@ public class ApplicationUser_resetPassword {
     
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
@@ -50,13 +50,13 @@ public class ApplicationUser_resetPassword {
             @ParameterLayout(named="Repeat password")
             final Password newPasswordRepeat) {
         
-        applicationUserRepository.updatePassword(holder, newPassword.getPassword());
-        return holder;
+        applicationUserRepository.updatePassword(target, newPassword.getPassword());
+        return target;
     }
 
     @Model
     public boolean hideAct() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(holder);
+        return !applicationUserRepository.isPasswordFeatureEnabled(target);
     }
 
     @Model
@@ -64,7 +64,7 @@ public class ApplicationUser_resetPassword {
             final Password newPassword,
             final Password newPasswordRepeat) {
         
-        if(!applicationUserRepository.isPasswordFeatureEnabled(holder)) {
+        if(!applicationUserRepository.isPasswordFeatureEnabled(target)) {
             return "Password feature is not available for this User";
         }
         
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java
index 6225ad3..8763975 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_unlock.java
@@ -36,16 +36,16 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationUser_unlock {
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act() {
-        holder.setStatus(ApplicationUserStatus.ENABLED);
-        return holder;
+        target.setStatus(ApplicationUserStatus.ENABLED);
+        return target;
     }
     
     @Model
     public String disableAct() {
-        return holder.getStatus() == ApplicationUserStatus.ENABLED ? "Status is already set to ENABLE": null;
+        return target.getStatus() == ApplicationUserStatus.ENABLED ? "Status is already set to ENABLE": null;
     }
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAccountType.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAccountType.java
index 8df97ad..bd4af6a 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
@@ -38,25 +38,25 @@ public class ApplicationUser_updateAccountType {
     
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
             final AccountType accountType) {
-        holder.setAccountType(accountType);
-        return holder;
+        target.setAccountType(accountType);
+        return target;
     }
     
     @Model
     public String disableUpdateAccountType() {
-        return applicationUserRepository.isAdminUser(holder)
+        return applicationUserRepository.isAdminUser(target)
                 ? "Cannot change account type for admin user"
                         : null;
     }
     
     @Model
     public AccountType default0UpdateAccountType() {
-        return holder.getAccountType();
+        return target.getAccountType();
     }
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java
index 803d604..74549b0 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateAtPath.java
@@ -36,20 +36,20 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationUser_updateAtPath {
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
             @Parameter(optionality = Optionality.OPTIONAL)
             @ParameterLayout(named = "AtPath")
             final String atPath) {
-        holder.setAtPath(atPath);
-        return holder;
+        target.setAtPath(atPath);
+        return target;
     }
 
     @Model
     public String default0Act() {
-        return holder.getAtPath();
+        return target.getAtPath();
     }
 
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java
index e894048..f7fc83f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateEmailAddress.java
@@ -35,25 +35,25 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationUser_updateEmailAddress {
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
             @Parameter(maxLength = ApplicationUser.MAX_LENGTH_EMAIL_ADDRESS)
             @ParameterLayout(named="Email")
             final String emailAddress) {
-        holder.setEmailAddress(emailAddress);
-        return holder;
+        target.setEmailAddress(emailAddress);
+        return target;
     }
 
     @Model
     public String default0Act() {
-        return holder.getEmailAddress();
+        return target.getEmailAddress();
     }
 
     @Model
     public String disableAct() {
-        return holder.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
+        return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java
index 73e1be6..4a3a8ba 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateName.java
@@ -36,7 +36,7 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationUser_updateName {
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
@@ -50,30 +50,30 @@ public class ApplicationUser_updateName {
             @ParameterLayout(named="Known As")
             final String knownAs
             ) {
-        holder.setFamilyName(familyName);
-        holder.setGivenName(givenName);
-        holder.setKnownAs(knownAs);
-        return holder;
+        target.setFamilyName(familyName);
+        target.setGivenName(givenName);
+        target.setKnownAs(knownAs);
+        return target;
     }
 
     @Model
     public String default0Act() {
-        return holder.getFamilyName();
+        return target.getFamilyName();
     }
 
     @Model
     public String default1Act() {
-        return holder.getGivenName();
+        return target.getGivenName();
     }
 
     @Model
     public String default2Act() {
-        return holder.getKnownAs();
+        return target.getKnownAs();
     }
 
     @Model
     public String disableAct() {
-        return holder.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
+        return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
 
     @Model
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 65fd58b..6f94637 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
@@ -46,7 +46,7 @@ public class ApplicationUser_updatePassword {
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private Optional<PasswordEncryptionService> passwordEncryptionService; // empty if no candidate is available
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
@@ -57,22 +57,22 @@ public class ApplicationUser_updatePassword {
             @ParameterLayout(named="Re-enter password")
             final Password newPasswordRepeat) {
         
-        applicationUserRepository.updatePassword(holder, newPassword.getPassword());
-        return holder;
+        applicationUserRepository.updatePassword(target, newPassword.getPassword());
+        return target;
     }
 
     @Model
     public boolean hideAct() {
-        return !applicationUserRepository.isPasswordFeatureEnabled(holder);
+        return !applicationUserRepository.isPasswordFeatureEnabled(target);
     }
 
     @Model
     public String disableAct() {
 
-        if(!holder.isForSelfOrRunAsAdministrator()) {
+        if(!target.isForSelfOrRunAsAdministrator()) {
             return "Can only update password for your own user account.";
         }
-        if (!holder.isHasPassword()) {
+        if (!target.isHasPassword()) {
             return "Password must be reset by administrator.";
         }
         return null;
@@ -84,15 +84,15 @@ public class ApplicationUser_updatePassword {
             final Password newPassword,
             final Password newPasswordRepeat) {
 
-        if(!applicationUserRepository.isPasswordFeatureEnabled(holder)) {
+        if(!applicationUserRepository.isPasswordFeatureEnabled(target)) {
             return "Password feature is not available for this User";
         }
 
         val encrypter = passwordEncryptionService.orElseThrow(_Exceptions::unexpectedCodeReach);
         
-        val encryptedPassword = holder.getEncryptedPassword();
+        val encryptedPassword = target.getEncryptedPassword();
         
-        if(holder.getEncryptedPassword() != null) {
+        if(target.getEncryptedPassword() != null) {
             if (!encrypter.matches(existingPassword.getPassword(), encryptedPassword)) {
                 return "Existing password is incorrect";
             }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java
index 15ec6ba..8c10425 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updatePhoneNumber.java
@@ -36,24 +36,24 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationUser_updatePhoneNumber {
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
             @ParameterLayout(named="Phone")
             @Parameter(maxLength = ApplicationUser.MAX_LENGTH_PHONE_NUMBER, optionality = Optionality.OPTIONAL)
             final String phoneNumber) {
-        holder.setPhoneNumber(phoneNumber);
-        return holder;
+        target.setPhoneNumber(phoneNumber);
+        return target;
     }
 
     @Model
     public String disableAct() {
-        return holder.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
+        return target.isForSelfOrRunAsAdministrator()? null: "Can only update your own user record.";
     }
     
     @Model
     public String default0Act() {
-        return holder.getPhoneNumber();
+        return target.getPhoneNumber();
     }
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java
index aad50c6..afef9be 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUser_updateUsername.java
@@ -35,20 +35,20 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationUser_updateUsername {
     
-    private final ApplicationUser holder;
+    private final ApplicationUser target;
 
     @Model
     public ApplicationUser act(
             @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
             @ParameterLayout(named="Username")
             final String username) {
-        holder.setUsername(username);
-        return holder;
+        target.setUsername(username);
+        return target;
     }
 
     @Model
     public String default0Act() {
-        return holder.getUsername();
+        return target.getUsername();
     }
 
 }
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 cb282c8..0222e45 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
@@ -40,25 +40,25 @@ public class HasUsername_open {
 
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     
-    private final HasUsername holder;
+    private final HasUsername target;
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<HasUsername_open> {}
 
     
     @MemberOrder(name = "User", sequence = "1") // associate with a 'User' property (if any)
     public ApplicationUser act() {
-        if (holder == null || holder.getUsername() == null) {
+        if (target == null || target.getUsername() == null) {
             return null;
         }
-        return applicationUserRepository.findByUsername(holder.getUsername()).orElse(null);
+        return applicationUserRepository.findByUsername(target.getUsername()).orElse(null);
     }
     
     public boolean hideAct() {
-        return holder instanceof ApplicationUser;
+        return target instanceof ApplicationUser;
     }
 
     public TranslatableString disableAct() {
-        if (holder == null || holder.getUsername() == null) {
+        if (target == null || target.getUsername() == null) {
             return TranslatableString.tr("No username");
         }
         return null;
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 b8b6ddf..d622e7f 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
@@ -37,15 +37,15 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ObjectContracts.ObjectContract;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValue;
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 67b5827..2fb948a 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
@@ -30,6 +30,8 @@ import javax.inject.Named;
 import org.springframework.stereotype.Repository;
 
 import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.message.MessageService;
@@ -43,9 +45,7 @@ import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.commons.internal.collections._Multimaps.ListMultimap;
 import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValue;
@@ -61,7 +61,7 @@ public class ApplicationPermissionRepository
 implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository<ApplicationPermission> {
 
     @Inject private RepositoryService repository;
-    @Inject private ApplicationFeatureRepositoryDefault applicationFeatureRepository;
+    @Inject private ApplicationFeatureRepositoryDefault featureRepository;
     @Inject private FactoryService factory;
     @Inject private MessageService messages;
     
@@ -231,7 +231,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
 
         final ApplicationFeatureId featureId = ApplicationFeatureId.newFeature(featureType, featureFqn);
-        final ApplicationFeature feature = applicationFeatureRepository.findFeature(featureId);
+        final ApplicationFeature feature = featureRepository.findFeature(featureId);
         if(feature == null) {
             messages.warnUser("No such " + featureType.name().toLowerCase() + ": " + featureFqn);
             return null;
@@ -270,13 +270,22 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final String featureClassName,
             final String featureMemberName) {
 
-        val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
-
         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 ApplicationFeatureId featureId) {
+
+        val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
         val featureType = featureId.getType();
         val featureFqn = featureId.getFullyQualifiedName();
 
-        val feature = applicationFeatureRepository.findFeature(featureId);
+        val feature = featureRepository.findFeature(featureId);
         if(feature == null) {
             messages.warnUser("No such " + featureType.name().toLowerCase() + ": " + featureFqn);
             return null;
@@ -292,7 +301,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
         return permission;
     }
-
+    
 
     // -- allPermission (programmatic)
     @Override
@@ -307,7 +316,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
     @Override
     public Collection<ApplicationPermission> findOrphaned() {
 
-        final Collection<String> packageNames = applicationFeatureRepository.packageNames();
+        final Collection<String> packageNames = featureRepository.packageNames();
         final Set<String> availableClasses = _Sets.newTreeSet();
         for (String packageName : packageNames) {
             appendClasses(packageName, ApplicationMemberType.PROPERTY, availableClasses);
@@ -317,8 +326,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
         val orphaned = _Lists.<ApplicationPermission>newArrayList();
 
-        val permissions = allPermissions();
-        for (val permission : permissions) {
+        for (val permission : allPermissions()) {
             final ApplicationFeatureType featureType = permission.getFeatureType();
             final String featureFqn = permission.getFeatureFqn();
 
@@ -360,7 +368,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
     private void appendClasses(
             final String packageName, final ApplicationMemberType memberType, final Set<String> availableClasses) {
-        final Collection<String> classNames = applicationFeatureRepository.classNamesContainedIn(packageName, memberType);
+        final Collection<String> classNames = featureRepository.classNamesContainedIn(packageName, memberType);
         for (String className : classNames) {
             availableClasses.add(packageName + "." + className);
         }
@@ -380,7 +388,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final ApplicationMemberType applicationMemberType,
             final List<String> memberNames) {
         final Collection<String> memberNamesOf =
-                applicationFeatureRepository.memberNamesOf(packageName, className, applicationMemberType);
+                featureRepository.memberNamesOf(packageName, className, applicationMemberType);
         memberNames.addAll(memberNamesOf);
     }
 
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 1d95fec..2abbe37 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
@@ -40,6 +40,7 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.user.RoleMemento;
 import org.apache.isis.applib.services.user.UserMemento;
 import org.apache.isis.applib.services.user.UserService;
@@ -47,7 +48,6 @@ import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ObjectContracts.ObjectContract;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValueSet;
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
index 40ac6e0..3763454 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
@@ -25,8 +25,8 @@ import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
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 914f41f..ab64170 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
@@ -45,15 +45,15 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ObjectContracts.ObjectContract;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValue;
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 8a2665d..52e2e1a 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
@@ -31,6 +31,8 @@ import javax.inject.Named;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.message.MessageService;
@@ -44,9 +46,7 @@ import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.commons.internal.collections._Multimaps.ListMultimap;
 import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValue;
@@ -278,7 +278,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,9 +288,19 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final String featureClassName,
             final String featureMemberName) {
 
-        val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
-
         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 ApplicationFeatureId featureId) {
+        
+        val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
+        
         val featureType = featureId.getType();
         val featureFqn = featureId.getFullyQualifiedName();
 
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 2f88229..db9b816 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
@@ -51,6 +51,7 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.services.user.RoleMemento;
 import org.apache.isis.applib.services.user.UserMemento;
 import org.apache.isis.applib.services.user.UserService;
@@ -58,7 +59,6 @@ import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ObjectContracts.ObjectContract;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValueSet;
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
index fb75029..4dbdb43 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
@@ -24,8 +24,8 @@ import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
diff --git a/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PermissionForMember.java b/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PermissionForMember.java
index 6ca9d74..bb8df0e 100644
--- a/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PermissionForMember.java
+++ b/extensions/security/secman/shiro-realm/src/main/java/org/apache/isis/extensions/secman/shiro/PermissionForMember.java
@@ -20,8 +20,8 @@ package org.apache.isis.extensions.secman.shiro;
 
 import org.apache.shiro.authz.Permission;
 
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
-import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 
 /**
  * As created by {@link org.apache.isis.extensions.secman.shiro.PermissionResolverForIsisShiroAuthorizor}, interprets the