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 2019/10/07 20:22:11 UTC

[isis] branch v2 updated: ISIS-1998: allows @Action on type as synonym for @Mixin(method="act")

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

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


The following commit(s) were added to refs/heads/v2 by this push:
     new a7dda4e  ISIS-1998: allows @Action on type as synonym for @Mixin(method="act")
a7dda4e is described below

commit a7dda4e02b192ff55329e008999fbc881e0f42a7
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Oct 7 22:21:59 2019 +0200

    ISIS-1998: allows @Action on type as synonym for @Mixin(method="act")
---
 .../apache/isis/applib/annotation/Property.java    |  3 +
 .../commons/internal/reflection/_Annotations.java  | 16 +++-
 .../apache/isis/metamodel/facets/FacetFactory.java | 63 +++++++++++++++-
 .../action/ActionAnnotationFacetFactory.java       | 56 +++++++-------
 .../property/PropertyAnnotationFacetFactory.java   | 67 ++++++++---------
 .../specloader/specimpl/FacetedMethodsBuilder.java | 64 +++++++++-------
 .../specimpl/ObjectSpecificationAbstract.java      |  4 +-
 .../traverser/SpecificationTraverser.java          |  6 +-
 .../action/ActionAnnotationFacetFactoryTest.java   |  2 +-
 ...nnotationFacetFactoryTest_ActionInvocation.java | 26 ++++---
 .../ActionAnnotationFacetFactoryTest_Command.java  | 34 +++++----
 .../ActionAnnotationFacetFactoryTest_Hidden.java   | 10 ++-
 ...ctionAnnotationFacetFactoryTest_Invocation.java | 25 ++++---
 ...ctionAnnotationFacetFactoryTest_Publishing.java | 34 +++++----
 ...ctionAnnotationFacetFactoryTest_RestrictTo.java | 14 +++-
 ...ActionAnnotationFacetFactoryTest_Semantics.java | 14 +++-
 .../ActionAnnotationFacetFactoryTest_TypeOf.java   | 17 +++--
 ...icsFacetFallbackToNonIdempotentFactoryTest.java | 11 ++-
 .../PrototypeFacetAnnotationFactoryTest.java       | 10 ++-
 ...sabledAnnotationOnPropertyFacetFactoryTest.java | 12 ++-
 .../MandatoryAnnotationFacetFactoryTest.java       | 10 ++-
 ...sistedAnnotationOnPropertyFacetFactoryTest.java | 10 ++-
 .../PropertyAnnotationFacetFactoryTest.java        | 87 +++++++++++++++++-----
 ...llableAnnotationOnPropertyFacetFactoryTest.java | 17 +++--
 .../RegExAnnotationOnPropertyFacetFactoryTest.java | 14 +++-
 .../model/good/ProperActionSupport_action.java     |  1 +
 ...tion.java => ProperActionSupport_property.java} | 13 ++--
 .../DomainModelTest_usingGoodDomain.java           |  3 +
 28 files changed, 443 insertions(+), 200 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
index ea9aecf..22d3a7b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
@@ -43,6 +43,9 @@ import org.apache.isis.applib.value.Clob;
 @Inherited
 @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
 @Retention(RetentionPolicy.RUNTIME)
+
+//@Action(semantics=SemanticsOf.SAFE)   
+//@ActionLayout(contributed=Contributed.AS_ASSOCIATION)
 @Mixin(method = "prop")
 public @interface Property {
 
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Annotations.java b/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Annotations.java
index 822cb79..12da77e 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Annotations.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Annotations.java
@@ -48,6 +48,20 @@ import lombok.val;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class _Annotations {
     
+    /**
+     * Determine if the specified annotation is either directly present or meta-present. 
+     * 
+     * @param <A>
+     * @param annotatedElement
+     * @param annotationType
+     * @return non-null
+     */
+    public static <A extends Annotation> boolean isPresent(
+            AnnotatedElement annotatedElement, 
+            Class<A> annotationType) {
+
+        return collect(annotatedElement).isPresent(annotationType);
+    }
     
     /**
      * Optionally returns the 'nearest' annotation of given type based on presence.
@@ -58,7 +72,7 @@ public final class _Annotations {
      * @return non-null
      */
     public static <A extends Annotation> Optional<A> findNearestAnnotation(
-            Class<?> annotatedElement, 
+            AnnotatedElement annotatedElement, 
             Class<A> annotationType) {
         //XXX if synthesize has good runtime performance, then we simply us it here
         return synthesize(annotatedElement, annotationType);
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/FacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/FacetFactory.java
index 75e7b9f..cb6dc45 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/FacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/FacetFactory.java
@@ -25,14 +25,21 @@ import java.lang.reflect.Parameter;
 import java.util.List;
 import java.util.Optional;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
+import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.reflection._Annotations;
+import org.apache.isis.metamodel.MetaModelContext;
 import org.apache.isis.metamodel.facetapi.Facet;
 import org.apache.isis.metamodel.facetapi.FacetHolder;
 import org.apache.isis.metamodel.facetapi.FeatureType;
 import org.apache.isis.metamodel.facetapi.MethodRemover;
 import org.apache.isis.metamodel.methodutils.MethodScope;
+import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState;
+import org.apache.isis.metamodel.specloader.specimpl.ObjectActionMixedIn;
+
+import lombok.val;
 
 public interface FacetFactory {
 
@@ -118,12 +125,62 @@ public interface FacetFactory {
         }
         
         /** 
-         * Annotation lookup on this context's method.
+         * Annotation lookup on this context's method..
          * @since 2.0
          */
         public <A extends Annotation> Optional<A> synthesizeOnMethod(Class<A> annotationType) {
             return _Annotations.synthesizeInherited(method, annotationType);
         }
+        
+        /** 
+         * Annotation lookup on this context's method, if not found, extends search to type in case 
+         * the predicate {@link #isMixinMain} evaluates {@code true}.
+         * @since 2.0
+         */
+        public <A extends Annotation> Optional<A> synthesizeOnMethodOrMixinType(Class<A> annotationType) {
+            return computeIfAbsent(synthesizeOnMethod(annotationType),
+                    ()-> isMixinMain()
+                        ? synthesizeOnType(annotationType)
+                                : Optional.empty() ) ;
+        }
+        
+        /**
+         * Whether we are currently processing a mixin type AND this context's method can be identified 
+         * as the main method of the processed mixin class.
+         * @since 2.0
+         */
+        public boolean isMixinMain() {
+            return isMixinMain.get();
+        }
+
+        private final _Lazy<Boolean> isMixinMain = _Lazy.threadSafe(this::computeIsMixinMain);
+        
+        private boolean computeIsMixinMain() {
+            val specLoader = MetaModelContext.current().getSpecificationLoader();
+            val spec_ofTypeCurrentlyProcessing = specLoader
+                    .loadSpecification(getCls(), IntrospectionState.TYPE_INTROSPECTED);
+            if(!spec_ofTypeCurrentlyProcessing.isMixin()) {
+                return false;
+            }
+            val mixinMember = spec_ofTypeCurrentlyProcessing
+                    .getMixedInMember(spec_ofTypeCurrentlyProcessing);
+            if(!mixinMember.isPresent()) {
+                return false;
+            }
+            val actionMethod_ofMixinMember = ((ObjectActionMixedIn)mixinMember.get())
+                    .getFacetedMethod().getMethod();
+            
+            return getMethod().equals(actionMethod_ofMixinMember);
+        }
+        
+        private static <T> Optional<T> computeIfAbsent(
+                Optional<T> optional,
+                Supplier<Optional<T>> supplier) {
+            
+            return optional.isPresent() ? 
+                    optional
+                        : supplier.get();
+        }
 
     }
 
@@ -203,7 +260,7 @@ public interface FacetFactory {
         public FeatureType getFeatureType() {
             return featureType;
         }
-
+        
     }
 
     /**
@@ -270,4 +327,6 @@ public interface FacetFactory {
      * annotation if present.
      */
     void processParams(ProcessParameterContext processParameterContext);
+
+    
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
index 69c1623..bdfcc1f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.metamodel.facets.actions.action;
 
+import java.util.Optional;
+
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
 import org.apache.isis.applib.services.HasUniqueId;
@@ -58,25 +60,28 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
 
     @Override
     public void process(final ProcessMethodContext processMethodContext) {
-
-        processInvocation(processMethodContext);
-        processHidden(processMethodContext);
-        processRestrictTo(processMethodContext);
-        processSemantics(processMethodContext);
+        
+        val actionIfAny = processMethodContext.synthesizeOnMethodOrMixinType(Action.class);
+        
+        processInvocation(processMethodContext, actionIfAny);
+        processHidden(processMethodContext, actionIfAny);
+        processRestrictTo(processMethodContext, actionIfAny);
+        processSemantics(processMethodContext, actionIfAny);
 
         // must come after processing semantics
-        processCommand(processMethodContext);
+        processCommand(processMethodContext, actionIfAny);
 
         // must come after processing semantics
-        processPublishing(processMethodContext);
+        processPublishing(processMethodContext, actionIfAny);
 
-        processTypeOf(processMethodContext);
-        processAssociateWith(processMethodContext);
+        processTypeOf(processMethodContext, actionIfAny);
+        processAssociateWith(processMethodContext, actionIfAny);
         
-        processFileAccept(processMethodContext);
+        processFileAccept(processMethodContext, actionIfAny);
     }
 
-    void processInvocation(final ProcessMethodContext processMethodContext) {
+
+    void processInvocation(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val actionMethod = processMethodContext.getMethod();
 
@@ -94,7 +99,7 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
             //
             // Set up ActionDomainEventFacet, which will act as the hiding/disabling/validating advisor
             //
-            val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+            
 
             // search for @Action(domainEvent=...), else use the default event type
             val actionDomainEventFacet =
@@ -152,37 +157,35 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         return actionDomainEventType;
     }
 
-    void processHidden(final ProcessMethodContext processMethodContext) {
+    void processHidden(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
         // search for @Action(hidden=...)
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         val facet = HiddenFacetForActionAnnotation.create(actionIfAny, holder);
         FacetUtil.addFacet(facet);
     }
 
-    void processRestrictTo(final ProcessMethodContext processMethodContext) {
+    void processRestrictTo(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
         // search for @Action(restrictTo=...)
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        @SuppressWarnings("deprecation")
         val facet = PrototypeFacetForActionAnnotation.create(actionIfAny, holder,
                 ()->IsisSystemEnvironment.get().getDeploymentType());
 
         FacetUtil.addFacet(facet);
     }
 
-    void processSemantics(final ProcessMethodContext processMethodContext) {
+    void processSemantics(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
         // check for @Action(semantics=...)
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         val facet = ActionSemanticsFacetForActionAnnotation.create(actionIfAny, holder);
 
         FacetUtil.addFacet(facet);
     }
 
-    void processCommand(final ProcessMethodContext processMethodContext) {
+    void processCommand(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val facetHolder = processMethodContext.getFacetHolder();
 
@@ -196,13 +199,12 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         }
 
         // check for @Action(command=...)
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         val commandFacet = CommandFacetForActionAnnotation.create(actionIfAny, getConfiguration(), getServiceInjector(), facetHolder);
 
         FacetUtil.addFacet(commandFacet);
     }
 
-    void processPublishing(final ProcessMethodContext processMethodContext) {
+    void processPublishing(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val holder = processMethodContext.getFacetHolder();
 
@@ -217,13 +219,12 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         }
 
         // check for @Action(publishing=...)
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         val facet = PublishedActionFacetForActionAnnotation.create(actionIfAny, getConfiguration(), holder);
 
         FacetUtil.addFacet(facet);
     }
 
-    void processTypeOf(final ProcessMethodContext processMethodContext) {
+    void processTypeOf(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val method = processMethodContext.getMethod();
         val holder = processMethodContext.getFacetHolder();
@@ -234,7 +235,6 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         }
 
         // check for @Action(typeOf=...)
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         TypeOfFacet typeOfFacet = actionIfAny
                 .map(Action::typeOf)
                 .filter(typeOf -> typeOf != null && typeOf != Object.class)
@@ -256,13 +256,12 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         FacetUtil.addFacet(typeOfFacet);
     }
 
-    void processAssociateWith(final ProcessMethodContext processMethodContext) {
+    void processAssociateWith(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val holder = processMethodContext.getFacetHolder();
 
         // check for @Action(associateWith=...)
 
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         actionIfAny.ifPresent(action->{
             val associateWith = action.associateWith();
             if(!_Strings.isNullOrEmpty(associateWith)) {
@@ -277,14 +276,11 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
 
     }
     
-    void processFileAccept(final ProcessMethodContext processMethodContext) {
+    void processFileAccept(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val holder = processMethodContext.getFacetHolder();
 
         // check for @Action(fileAccept=...)
-
-        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
-        
         val facet = FileAcceptFacetForActionAnnotation.create(actionIfAny, holder);
         FacetUtil.addFacet(facet);
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
index 1fdfcd5..dbf9c7c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.metamodel.facets.properties.property;
 
+import java.util.Optional;
+
 import javax.annotation.Nullable;
 import javax.validation.constraints.Pattern;
 
@@ -70,25 +72,28 @@ implements MetaModelRefiner {
     public PropertyAnnotationFacetFactory() {
         super(FeatureType.PROPERTIES_AND_ACTIONS);
     }
-
+    
     @Override
     public void process(final ProcessMethodContext processMethodContext) {
-        processModify(processMethodContext);
-        processHidden(processMethodContext);
-        processEditing(processMethodContext);
-        processCommand(processMethodContext);
-        processProjecting(processMethodContext);
-        processPublishing(processMethodContext);
-        processMaxLength(processMethodContext);
-        processMustSatisfy(processMethodContext);
-        processNotPersisted(processMethodContext);
-        processOptional(processMethodContext);
-        processRegEx(processMethodContext);
-        processFileAccept(processMethodContext);
+        
+        val propertyIfAny = processMethodContext.synthesizeOnMethodOrMixinType(Property.class);
+        
+        processModify(processMethodContext, propertyIfAny);
+        processHidden(processMethodContext, propertyIfAny);
+        processEditing(processMethodContext, propertyIfAny);
+        processCommand(processMethodContext, propertyIfAny);
+        processProjecting(processMethodContext, propertyIfAny);
+        processPublishing(processMethodContext, propertyIfAny);
+        processMaxLength(processMethodContext, propertyIfAny);
+        processMustSatisfy(processMethodContext, propertyIfAny);
+        processNotPersisted(processMethodContext, propertyIfAny);
+        processOptional(processMethodContext, propertyIfAny);
+        processRegEx(processMethodContext, propertyIfAny);
+        processFileAccept(processMethodContext, propertyIfAny);
     }
 
 
-    void processModify(final ProcessMethodContext processMethodContext) {
+    void processModify(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
 
         val cls = processMethodContext.getCls();
         val typeSpec = getSpecificationLoader().loadSpecification(cls);
@@ -106,7 +111,6 @@ implements MetaModelRefiner {
         //
         // Set up PropertyDomainEventFacet, which will act as the hiding/disabling/validating advisor
         //
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
 
         // search for @Property(domainEvent=...), else use default event type
         val propertyDomainEventFacet = propertyIfAny
@@ -183,27 +187,25 @@ implements MetaModelRefiner {
 
 
 
-    void processHidden(final ProcessMethodContext processMethodContext) {
+    void processHidden(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val facetHolder = processMethodContext.getFacetHolder();
         
         // search for @Property(hidden=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val hiddenFacet = HiddenFacetForPropertyAnnotation.create(propertyIfAny, facetHolder);
 
         FacetUtil.addFacet(hiddenFacet);
     }
 
-    void processEditing(final ProcessMethodContext processMethodContext) {
+    void processEditing(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val facetHolder = processMethodContext.getFacetHolder();
 
         // search for @Property(editing=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val disabledFacet = DisabledFacetForPropertyAnnotation.create(propertyIfAny, facetHolder);
 
         FacetUtil.addFacet(disabledFacet);
     }
 
-    void processCommand(final ProcessMethodContext processMethodContext) {
+    void processCommand(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val facetHolder = processMethodContext.getFacetHolder();
 
         //
@@ -216,17 +218,15 @@ implements MetaModelRefiner {
         }
 
         // check for @Property(command=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val commandFacet = CommandFacetForPropertyAnnotation
                 .create(propertyIfAny, getConfiguration(), facetHolder, getServiceInjector());
 
         FacetUtil.addFacet(commandFacet);
     }
 
-    void processProjecting(final ProcessMethodContext processMethodContext) {
+    void processProjecting(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
 
         val facetHolder = processMethodContext.getFacetHolder();
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
 
         val projectingFacet = ProjectingFacetFromPropertyAnnotation
                 .create(propertyIfAny, facetHolder);
@@ -235,7 +235,7 @@ implements MetaModelRefiner {
 
     }
 
-    void processPublishing(final ProcessMethodContext processMethodContext) {
+    void processPublishing(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
 
         
         val holder = processMethodContext.getFacetHolder();
@@ -251,7 +251,6 @@ implements MetaModelRefiner {
         }
 
         // check for @Property(publishing=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet = PublishedPropertyFacetForPropertyAnnotation
                 .create(propertyIfAny, getConfiguration(), holder);
 
@@ -260,38 +259,35 @@ implements MetaModelRefiner {
 
 
 
-    void processMaxLength(final ProcessMethodContext processMethodContext) {
+    void processMaxLength(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
 
         val holder = processMethodContext.getFacetHolder();
 
         // search for @Property(maxLength=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet = MaxLengthFacetForPropertyAnnotation.create(propertyIfAny, holder);
 
         FacetUtil.addFacet(facet);
     }
 
-    void processMustSatisfy(final ProcessMethodContext processMethodContext) {
+    void processMustSatisfy(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
         // search for @Property(mustSatisfy=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet = MustSatisfySpecificationFacetForPropertyAnnotation.create(propertyIfAny, holder, getServiceInjector());
 
         FacetUtil.addFacet(facet);
     }
 
-    void processNotPersisted(final ProcessMethodContext processMethodContext) {
+    void processNotPersisted(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
         // search for @Property(notPersisted=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet = NotPersistedFacetForPropertyAnnotation.create(propertyIfAny, holder);
 
         FacetUtil.addFacet(facet);
     }
 
-    void processOptional(final ProcessMethodContext processMethodContext) {
+    void processOptional(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
 
         val method = processMethodContext.getMethod();
 
@@ -306,14 +302,13 @@ implements MetaModelRefiner {
                 facet2, "Conflicting @Nullable with other optionality annotation");
 
         // search for @Property(optional=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet3 = MandatoryFacetForPropertyAnnotation.create(propertyIfAny, method, holder);
         FacetUtil.addFacet(facet3);
         conflictingOptionalityValidator.flagIfConflict(
                 facet3, "Conflicting Property#optionality with other optionality annotation");
     }
 
-    void processRegEx(final ProcessMethodContext processMethodContext) {
+    void processRegEx(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val holder = processMethodContext.getFacetHolder();
         val returnType = processMethodContext.getMethod().getReturnType();
 
@@ -327,7 +322,6 @@ implements MetaModelRefiner {
         }
         
         // else search for @Property(pattern=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet2 = RegExFacetForPropertyAnnotation.create(propertyIfAny, returnType, holder);
         FacetUtil.addFacet(facet2);
         
@@ -335,11 +329,10 @@ implements MetaModelRefiner {
     }
 
 
-    void processFileAccept(final ProcessMethodContext processMethodContext) {
+    void processFileAccept(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
         // else search for @Property(maxLength=...)
-        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
         val facet = FileAcceptFacetForPropertyAnnotation.create(propertyIfAny, holder);
 
         FacetUtil.addFacet(facet);
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index 19592a8..195f09e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@ -33,13 +33,13 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.commons.exceptions.IsisException;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Sets;
+import org.apache.isis.commons.internal.reflection._Annotations;
 import org.apache.isis.metamodel.MetaModelContext;
 import org.apache.isis.metamodel.commons.MethodUtil;
 import org.apache.isis.metamodel.commons.ToString;
 import org.apache.isis.metamodel.exceptions.MetaModelException;
 import org.apache.isis.metamodel.facetapi.FeatureType;
 import org.apache.isis.metamodel.facetapi.MethodRemover;
-import org.apache.isis.metamodel.facets.Annotations;
 import org.apache.isis.metamodel.facets.FacetFactory;
 import org.apache.isis.metamodel.facets.FacetFactory.ProcessClassContext;
 import org.apache.isis.metamodel.facets.FacetedMethod;
@@ -125,7 +125,7 @@ public class FacetedMethodsBuilder {
         
     }
 
-    private final ObjectSpecificationAbstract spec;
+    private final ObjectSpecificationAbstract inspectedTypeSpec;
 
     private final Class<?> introspectedClass;
    // private final Set<Method> methodsRemaining;
@@ -157,7 +157,7 @@ public class FacetedMethodsBuilder {
             log.debug("creating JavaIntrospector for {}", spec.getFullIdentifier());
         }
 
-        this.spec = spec;
+        this.inspectedTypeSpec = spec;
         this.introspectedClass = spec.getCorrespondingClass();
         
         val methodsRemaining = introspectedClass.getMethods();
@@ -189,7 +189,7 @@ public class FacetedMethodsBuilder {
         if (log.isDebugEnabled()) {
             log.debug("introspecting {}: objectSpecId", getClassName());
         }
-        getFacetProcessor().processObjectSpecId(introspectedClass, spec);
+        getFacetProcessor().processObjectSpecId(introspectedClass, inspectedTypeSpec);
     }
     public void introspectClass() {
         if (log.isDebugEnabled()) {
@@ -199,11 +199,11 @@ public class FacetedMethodsBuilder {
         // process facets at object level
         // this will also remove some methods, such as the superclass methods.
 
-        getFacetProcessor().process(introspectedClass, methodRemover, spec);
+        getFacetProcessor().process(introspectedClass, methodRemover, inspectedTypeSpec);
 
         // if this class has additional facets (as per @Facets), then process
         // them.
-        final FacetsFacet facetsFacet = spec.getFacet(FacetsFacet.class);
+        final FacetsFacet facetsFacet = inspectedTypeSpec.getFacet(FacetsFacet.class);
         if (facetsFacet != null) {
             final Class<? extends FacetFactory>[] facetFactories = facetsFacet.facetFactories();
             for (final Class<? extends FacetFactory> facetFactorie : facetFactories) {
@@ -214,7 +214,7 @@ public class FacetedMethodsBuilder {
                     throw new IsisException(e);
                 }
                 getFacetProcessor().injectDependenciesInto(facetFactory);
-                facetFactory.process(new ProcessClassContext(introspectedClass, methodRemover, spec));
+                facetFactory.process(new ProcessClassContext(introspectedClass, methodRemover, inspectedTypeSpec));
             }
         }
 
@@ -248,9 +248,9 @@ public class FacetedMethodsBuilder {
         });
 
         // Ensure all return types are known
-        final Set<Class<?>> typesToLoad = _Sets.newHashSet();
-        for (final Method method : associationCandidateMethods) {
-            specificationTraverser.traverseTypes(method, typesToLoad);
+        val typesToLoad = _Sets.<Class<?>>newHashSet();
+        for (val method : associationCandidateMethods) {
+            specificationTraverser.traverseTypes(method, typesToLoad::add);
         }
         typesToLoad.remove(introspectedClass);
 
@@ -357,16 +357,17 @@ public class FacetedMethodsBuilder {
 
     private List<FacetedMethod> findActionFacetedMethods(
             final MethodScope methodScope) {
+        
         if (log.isDebugEnabled()) {
             log.debug("introspecting {}: actions", getClassName());
         }
         val actionFacetedMethods = _Lists.<FacetedMethod>newArrayList();
-        collectActionFacetedMethods(actionFacetedMethods, methodScope);
+        collectActionFacetedMethods(actionFacetedMethods::add, methodScope);
         return actionFacetedMethods;
     }
 
     private void collectActionFacetedMethods(
-            final List<FacetedMethod> actionFacetedMethods,
+            final Consumer<FacetedMethod> onActionFacetedMethod,
             final MethodScope methodScope) {
 
         if (log.isDebugEnabled()) {
@@ -376,7 +377,7 @@ public class FacetedMethodsBuilder {
         methodRemover.removeIf(method->{
             val actionPeer = findActionFacetedMethod(methodScope, method);
             if (actionPeer != null) {
-                actionFacetedMethods.add(actionPeer);
+                onActionFacetedMethod.accept(actionPeer);
                 return true;
             }
             return false;
@@ -434,14 +435,13 @@ public class FacetedMethodsBuilder {
             return false;
         }
 
-        final Set<Class<?>> typesToLoad = _Sets.newHashSet();
-        specificationTraverser.traverseTypes(actionMethod, typesToLoad);
+        val typesToLoad = _Sets.<Class<?>>newHashSet();
+        specificationTraverser.traverseTypes(actionMethod, typesToLoad::add);
 
         val specLoader = getSpecificationLoader();
-        val upTo = IntrospectionState.TYPE_INTROSPECTED;
 
         val anyLoadedAsNull = typesToLoad.stream()
-                .map(typeToLoad->specLoader.loadSpecification(typeToLoad, upTo))
+                .map(typeToLoad->specLoader.loadSpecification(typeToLoad, IntrospectionState.TYPE_INTROSPECTED))
                 .anyMatch(spec->spec==null);
 
         if (anyLoadedAsNull) {
@@ -452,27 +452,35 @@ public class FacetedMethodsBuilder {
         if (!loadParamSpecs(actionMethod)) {
             return false;
         }
-
+        
+        if(this.inspectedTypeSpec.isMixin()) {
+            // we are introspecting a mixin type, so accept this method for further processing
+            log.debug("  identified possible mixin´s 'main' action {0}", actionMethod);
+            return true;
+        } 
+        
         if(explicitActionAnnotationConfigured()) {
-            if(!Annotations.isAnnotationPresent(actionMethod, Action.class)) {
-                return false;
-            }
-            // we have @Action, so fall through
             
-        } else {
-
-            // exclude those that have eg. reserved prefixes
-            if (getFacetProcessor().recognizes(actionMethod)) {
-                return false;
+            if(_Annotations.isPresent(actionMethod, Action.class)) {
+                log.debug("  identified action {0}", actionMethod);
+                return true;
             }
-            // we have a valid action candidate, so fall through
+            // we have no @Action, so dismiss
+            return false;
             
+        } 
+
+        // exclude those that have eg. reserved prefixes
+        if (getFacetProcessor().recognizes(actionMethod)) {
+            return false;
         }
+        // we have a valid action candidate, so fall through
         
         log.debug("  identified action {0}", actionMethod);
         return true;
     }
 
+
     private boolean explicitActionAnnotationConfigured() {
         return explicitAnnotationsForActions;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index a33dd2a..ecf7db5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -502,8 +502,6 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
         return superclassSpec != null && superclassSpec.isOfType(specification);
     }
 
-
-
     // -- Name, Description, Persistability
     /**
      * The name according to any available {@link org.apache.isis.metamodel.facets.all.named.NamedFacet},
@@ -1330,4 +1328,6 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
         return BeanSort.UNKNOWN;
     }
 
+
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/traverser/SpecificationTraverser.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/traverser/SpecificationTraverser.java
index d5a86f1..6ad9798 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/traverser/SpecificationTraverser.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/traverser/SpecificationTraverser.java
@@ -20,7 +20,7 @@
 package org.apache.isis.metamodel.specloader.traverser;
 
 import java.lang.reflect.Method;
-import java.util.Collection;
+import java.util.function.Consumer;
 
 public class SpecificationTraverser {
 
@@ -31,8 +31,8 @@ public class SpecificationTraverser {
      * It's possible for there to be multiple return types: the generic type,
      * and the parameterized type.
      */
-    public void traverseTypes(final Method method, final Collection<Class<?>> discoveredTypes) {
-        new TypeExtractorMethodReturn(method).forEach(discoveredTypes::add);
+    public void traverseTypes(final Method method, final Consumer<Class<?>> onTypeDiscovered) {
+        new TypeExtractorMethodReturn(method).forEach(onTypeDiscovered);
     }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java
index d78fb6e..8720701 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java
@@ -57,7 +57,7 @@ public class ActionAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4
         context.checking(new Expectations() {{
             allowing(mockSpecificationLoader).loadSpecification(cls);
             will(returnValue(mockTypeSpec));
-
+            
             allowing(mockSpecificationLoader).loadSpecification(returnType);
             will(returnValue(mockReturnTypeSpec));
         }});
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_ActionInvocation.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_ActionInvocation.java
index 6b0600a..17a6f49 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_ActionInvocation.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_ActionInvocation.java
@@ -21,7 +21,7 @@ package org.apache.isis.metamodel.facets.actions.action;
 
 import java.lang.reflect.Method;
 
-import org.apache.isis.metamodel.MetaModelContext;
+import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.metamodel.facetapi.Facet;
 import org.apache.isis.metamodel.facets.AbstractFacetFactoryTest;
 import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
@@ -37,6 +37,8 @@ import org.apache.isis.metamodel.facets.param.choices.methodnum.ActionParameterC
 import org.apache.isis.metamodel.spec.ObjectSpecification;
 import org.apache.isis.metamodel.testspec.ObjectSpecificationStub;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractFacetFactoryTest {
 
     private final ObjectSpecification voidSpec = new ObjectSpecificationStub("VOID");
@@ -44,14 +46,16 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
     private final ObjectSpecification customerSpec = new ObjectSpecificationStub("Customer");
     private ActionAnnotationFacetFactory facetFactory;
 
+    private void processInvocation(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processInvocation(processMethodContext, actionIfAny);
+    }
+    
     @Override
     public void setUp() throws Exception {
         super.setUp();
         this.facetFactory =  new ActionAnnotationFacetFactory();
-
-        System.out.println("setup " + MetaModelContext.current().getSpecificationLoader());
-
-
     }
 
     public void testActionInvocationFacetIsInstalledAndMethodRemoved() {
@@ -65,7 +69,7 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
         }
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processInvocation(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processInvocation(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(ActionInvocationFacet.class);
         assertNotNull(facet);
@@ -87,7 +91,7 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
         }
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processInvocation(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processInvocation(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(ActionInvocationFacet.class);
         final ActionInvocationFacetForDomainEventAbstract actionInvocationFacetViaMethod = (ActionInvocationFacetForDomainEventAbstract) facet;
@@ -106,7 +110,7 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
         }
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processInvocation(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processInvocation(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(ActionInvocationFacet.class);
         final ActionInvocationFacetForDomainEventAbstract actionInvocationFacetViaMethod = (ActionInvocationFacetForDomainEventAbstract) facet;
@@ -125,7 +129,7 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
         }
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processInvocation(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processInvocation(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(ActionInvocationFacet.class);
         final ActionInvocationFacetForDomainEventAbstract actionInvocationFacetViaMethod = (ActionInvocationFacetForDomainEventAbstract) facet;
@@ -149,7 +153,7 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
 
         final FacetedMethod facetHolderWithParms = FacetedMethod.createForAction(CustomerEx.class, actionMethod);
 
-        facetFactory.processInvocation(new ProcessMethodContext(CustomerEx.class, null, actionMethod, methodRemover, facetHolderWithParms));
+        processInvocation(facetFactory, new ProcessMethodContext(CustomerEx.class, null, actionMethod, methodRemover, facetHolderWithParms));
 
         final Facet facet0 = facetHolderWithParms.getFacet(ActionInvocationFacet.class);
         assertNotNull(facet0);
@@ -198,7 +202,7 @@ public class ActionAnnotationFacetFactoryTest_ActionInvocation extends AbstractF
         final FacetedMethod facetHolderWithParms = FacetedMethod.createForAction(CustomerEx.class, actionMethod);
 
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(CustomerEx.class, null, actionMethod, methodRemover, facetHolderWithParms);
-        facetFactory.processInvocation(processMethodContext);
+        processInvocation(facetFactory, processMethodContext);
 
         facetFactoryForChoices.process(processMethodContext);
         facetFactoryForDisable.process(processMethodContext);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Command.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Command.java
index 3808d3e..021988e 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Command.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Command.java
@@ -43,15 +43,23 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFacetFactoryTest {
 
+    private void processCommand(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processCommand(processMethodContext, actionIfAny);
+    }
+    
     @Test
     public void givenHasTransactionId_thenIgnored() {
         // given
         final Method actionMethod = findMethod(SomeTransactionalId.class, "someAction");
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(SomeTransactionalId.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(SomeTransactionalId.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
@@ -69,7 +77,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.SAFE, facetedMethod) {});
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processCommand(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -87,7 +95,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.IDEMPOTENT, facetedMethod) {});
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processCommand(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -107,7 +115,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         final Method actionMethod = findMethod(ActionAnnotationFacetFactoryTest.Customer.class, "someAction");
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processCommand(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
     }
 
@@ -119,7 +127,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         final Method actionMethod = findMethod(ActionAnnotationFacetFactoryTest.Customer.class, "someAction");
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processCommand(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -136,7 +144,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         allowingCommandConfigurationToReturn(CommandActionsConfiguration.ALL);
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processCommand(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -159,7 +167,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
 
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.SAFE, facetedMethod) {});
 
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
         assertNull(facet);
@@ -185,7 +193,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.IDEMPOTENT, facetedMethod) {});
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
@@ -207,7 +215,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         allowingCommandConfigurationToReturn(CommandActionsConfiguration.IGNORE_QUERY_ONLY);
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
     }
 
     @Test
@@ -222,7 +230,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         allowingCommandConfigurationToReturn(CommandActionsConfiguration.NONE);
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
         assertNull(facet);
@@ -246,7 +254,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         allowingCommandConfigurationToReturn(CommandActionsConfiguration.ALL);
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
@@ -271,7 +279,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         allowingCommandConfigurationToReturn(CommandActionsConfiguration.NONE);
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
@@ -294,7 +302,7 @@ public class ActionAnnotationFacetFactoryTest_Command extends ActionAnnotationFa
         allowingCommandConfigurationToReturn(CommandActionsConfiguration.NONE);
 
         // when
-        facetFactory.processCommand(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommand(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(CommandFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Hidden.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Hidden.java
index c0860f6..b1b4e50 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Hidden.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Hidden.java
@@ -31,8 +31,16 @@ import org.apache.isis.metamodel.facets.all.hide.HiddenFacet;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_Hidden extends ActionAnnotationFacetFactoryTest {
 
+    private void processHidden(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processHidden(processMethodContext, actionIfAny);
+    }
+    
     @Test
     public void withAnnotation() {
 
@@ -49,7 +57,7 @@ public class ActionAnnotationFacetFactoryTest_Hidden extends ActionAnnotationFac
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processHidden(processMethodContext);
+        processHidden(facetFactory, processMethodContext);
 
         // then
         final HiddenFacet hiddenFacet = facetedMethod.getFacet(HiddenFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Invocation.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Invocation.java
index 7102b7b..85e0f40 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Invocation.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Invocation.java
@@ -37,15 +37,22 @@ import org.apache.isis.metamodel.facets.actions.action.invocation.ActionInvocati
 import static org.apache.isis.metamodel.commons.matchers.IsisMatchers.classEqualTo;
 import static org.junit.Assert.assertThat;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotationFacetFactoryTest {
 
+    private void processInvocation(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processInvocation(processMethodContext, actionIfAny);
+    }
+    
     @Test
     public void withPostsActionInvokedEvent() {
 
         class Customer {
 
-            class SomeActionInvokedDomainEvent extends ActionDomainEvent<Customer> {
-                private static final long serialVersionUID = 1L; }
+            class SomeActionInvokedDomainEvent extends ActionDomainEvent<Customer> {}
 
             @Action(domainEvent = SomeActionInvokedDomainEvent.class)
             public void someAction() {
@@ -65,7 +72,7 @@ public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processInvocation(processMethodContext);
+        processInvocation(facetFactory, processMethodContext);
 
         // then
         final ActionDomainEventFacet domainEventFacet = facetedMethod.getFacet(ActionDomainEventFacet.class);
@@ -86,8 +93,7 @@ public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotatio
 
         class Customer {
 
-            class SomeActionInvokedDomainEvent extends ActionDomainEvent<Customer> {
-                private static final long serialVersionUID = 1L; }
+            class SomeActionInvokedDomainEvent extends ActionDomainEvent<Customer> {}
 
             @Action(domainEvent = SomeActionInvokedDomainEvent.class)
             public void someAction() {
@@ -105,7 +111,7 @@ public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processInvocation(processMethodContext);
+        processInvocation(facetFactory, processMethodContext);
 
         // then
         final Facet domainEventFacet = facetedMethod.getFacet(ActionDomainEventFacet.class);
@@ -129,8 +135,7 @@ public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotatio
 
         class Customer {
 
-            class SomeActionInvokedDomainEvent extends ActionDomainEvent<Customer> {
-                private static final long serialVersionUID = 1L; }
+            class SomeActionInvokedDomainEvent extends ActionDomainEvent<Customer> {}
 
             @Action(domainEvent= SomeActionInvokedDomainEvent.class)
             public void someAction() {
@@ -148,7 +153,7 @@ public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processInvocation(processMethodContext);
+        processInvocation(facetFactory, processMethodContext);
 
         // then
         final Facet domainEventFacet = facetedMethod.getFacet(ActionDomainEventFacet.class);
@@ -186,7 +191,7 @@ public class ActionAnnotationFacetFactoryTest_Invocation extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processInvocation(processMethodContext);
+        processInvocation(facetFactory, processMethodContext);
 
         // then
         final Facet domainEventFacet = facetedMethod.getFacet(ActionDomainEventFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Publishing.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Publishing.java
index 7820798..2f35504 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Publishing.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Publishing.java
@@ -37,14 +37,22 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotationFacetFactoryTest {
 
+    private void processPublishing(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processPublishing(processMethodContext, actionIfAny);
+    }
+    
     @Test
     public void givenHasTransactionId_thenIgnored() {
 
         final Method actionMethod = findMethod(SomeTransactionalId.class, "someAction");
 
-        facetFactory.processPublishing(new ProcessMethodContext(SomeTransactionalId.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(SomeTransactionalId.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
         assertNull(facet);
@@ -62,7 +70,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.SAFE, facetedMethod) {});
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processPublishing(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -80,7 +88,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.IDEMPOTENT, facetedMethod) {});
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processPublishing(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -98,7 +106,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         final Method actionMethod = findMethod(ActionAnnotationFacetFactoryTest.Customer.class, "someAction");
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processPublishing(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
     }
@@ -111,7 +119,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         final Method actionMethod = findMethod(ActionAnnotationFacetFactoryTest.Customer.class, "someAction");
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processPublishing(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -131,7 +139,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         allowingPublishingConfigurationToReturn(PublishActionsConfiguration.ALL);
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
+        processPublishing(facetFactory, new ProcessMethodContext(ActionAnnotationFacetFactoryTest.Customer.class, null,
                 actionMethod, mockMethodRemover, facetedMethod));
 
         // then
@@ -154,7 +162,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
 
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.SAFE, facetedMethod) {});
 
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
         assertNull(facet);
@@ -180,7 +188,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         facetedMethod.addFacet(new ActionSemanticsFacetAbstract(SemanticsOf.IDEMPOTENT, facetedMethod) {});
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
@@ -203,7 +211,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         allowingPublishingConfigurationToReturn(PublishActionsConfiguration.IGNORE_QUERY_ONLY);
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
     }
 
     @Test
@@ -218,7 +226,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         allowingPublishingConfigurationToReturn(PublishActionsConfiguration.NONE);
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
         assertNull(facet);
@@ -243,7 +251,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         allowingPublishingConfigurationToReturn(PublishActionsConfiguration.ALL);
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
@@ -270,7 +278,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         allowingPublishingConfigurationToReturn(PublishActionsConfiguration.NONE);
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
@@ -295,7 +303,7 @@ public class ActionAnnotationFacetFactoryTest_Publishing extends ActionAnnotatio
         allowingPublishingConfigurationToReturn(PublishActionsConfiguration.NONE);
 
         // when
-        facetFactory.processPublishing(new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processPublishing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         final Facet facet = facetedMethod.getFacet(PublishedActionFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java
index f71a19c..46cf7cf 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java
@@ -27,8 +27,16 @@ import org.apache.isis.metamodel.facets.actions.prototype.PrototypeFacet;
 
 import static org.junit.Assert.assertNull;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_RestrictTo extends ActionAnnotationFacetFactoryTest {
 
+    private void processRestrictTo(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processRestrictTo(processMethodContext, actionIfAny);
+    }
+    
     @Test
     public void whenRestrictedToPrototyping() {
 
@@ -45,7 +53,7 @@ public class ActionAnnotationFacetFactoryTest_RestrictTo extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processRestrictTo(processMethodContext);
+        processRestrictTo(facetFactory, processMethodContext);
 
         // then
         final PrototypeFacet facet = facetedMethod.getFacet(PrototypeFacet.class);
@@ -68,7 +76,7 @@ public class ActionAnnotationFacetFactoryTest_RestrictTo extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processRestrictTo(processMethodContext);
+        processRestrictTo(facetFactory, processMethodContext);
 
         // then
         final PrototypeFacet facet = facetedMethod.getFacet(PrototypeFacet.class);
@@ -91,7 +99,7 @@ public class ActionAnnotationFacetFactoryTest_RestrictTo extends ActionAnnotatio
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(
                 cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processRestrictTo(processMethodContext);
+        processRestrictTo(facetFactory, processMethodContext);
 
         // then
         final PrototypeFacet facet = facetedMethod.getFacet(PrototypeFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Semantics.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Semantics.java
index 49f6670..772203f 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Semantics.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_Semantics.java
@@ -29,8 +29,16 @@ import org.apache.isis.metamodel.facets.actions.semantics.ActionSemanticsFacet;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_Semantics extends ActionAnnotationFacetFactoryTest {
 
+    private void processSemantics(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processSemantics(processMethodContext, actionIfAny);
+    }
+    
     @Test
     public void whenSafe() {
 
@@ -46,7 +54,7 @@ public class ActionAnnotationFacetFactoryTest_Semantics extends ActionAnnotation
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processSemantics(processMethodContext);
+        processSemantics(facetFactory, processMethodContext);
 
         // then
         final ActionSemanticsFacet facet = facetedMethod.getFacet(ActionSemanticsFacet.class);
@@ -69,7 +77,7 @@ public class ActionAnnotationFacetFactoryTest_Semantics extends ActionAnnotation
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processSemantics(processMethodContext);
+        processSemantics(facetFactory, processMethodContext);
 
         // then
         final ActionSemanticsFacet facet = facetedMethod.getFacet(ActionSemanticsFacet.class);
@@ -92,7 +100,7 @@ public class ActionAnnotationFacetFactoryTest_Semantics extends ActionAnnotation
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processSemantics(processMethodContext);
+        processSemantics(facetFactory, processMethodContext);
 
         // then
         final ActionSemanticsFacet facet = facetedMethod.getFacet(ActionSemanticsFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_TypeOf.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_TypeOf.java
index 3bbd96e..0dcf065 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_TypeOf.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_TypeOf.java
@@ -33,8 +33,15 @@ import org.apache.isis.metamodel.facets.actions.action.typeof.TypeOfFacetForActi
 import static org.apache.isis.metamodel.commons.matchers.IsisMatchers.classEqualTo;
 import static org.junit.Assert.assertThat;
 
+import lombok.val;
+
 public class ActionAnnotationFacetFactoryTest_TypeOf extends ActionAnnotationFacetFactoryTest {
 
+    private void processTypeOf(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processTypeOf(processMethodContext, actionIfAny);
+    }
 
     @Test
     public void whenDeprecatedTypeOfAnnotationOnActionNotReturningCollection() {
@@ -52,7 +59,7 @@ public class ActionAnnotationFacetFactoryTest_TypeOf extends ActionAnnotationFac
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processTypeOf(processMethodContext);
+        processTypeOf(facetFactory, processMethodContext);
 
         // then
         final TypeOfFacet facet = facetedMethod.getFacet(TypeOfFacet.class);
@@ -78,7 +85,7 @@ public class ActionAnnotationFacetFactoryTest_TypeOf extends ActionAnnotationFac
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processTypeOf(processMethodContext);
+        processTypeOf(facetFactory, processMethodContext);
 
         // then
         final TypeOfFacet facet = facetedMethod.getFacet(TypeOfFacet.class);
@@ -105,7 +112,7 @@ public class ActionAnnotationFacetFactoryTest_TypeOf extends ActionAnnotationFac
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processTypeOf(processMethodContext);
+        processTypeOf(facetFactory, processMethodContext);
 
         // then
         final TypeOfFacet facet = facetedMethod.getFacet(TypeOfFacet.class);
@@ -130,7 +137,7 @@ public class ActionAnnotationFacetFactoryTest_TypeOf extends ActionAnnotationFac
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processTypeOf(processMethodContext);
+        processTypeOf(facetFactory, processMethodContext);
 
         // then
         final TypeOfFacet facet = facetedMethod.getFacet(TypeOfFacet.class);
@@ -157,7 +164,7 @@ public class ActionAnnotationFacetFactoryTest_TypeOf extends ActionAnnotationFac
 
         // when
         final ProcessMethodContext processMethodContext = new ProcessMethodContext(cls, null, actionMethod, mockMethodRemover, facetedMethod);
-        facetFactory.processTypeOf(processMethodContext);
+        processTypeOf(facetFactory, processMethodContext);
 
         // then
         final TypeOfFacet facet = facetedMethod.getFacet(TypeOfFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionSemanticsFacetFallbackToNonIdempotentFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionSemanticsFacetFallbackToNonIdempotentFactoryTest.java
index c2e2a88..e73a7cf 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionSemanticsFacetFallbackToNonIdempotentFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/ActionSemanticsFacetFallbackToNonIdempotentFactoryTest.java
@@ -21,15 +21,24 @@ package org.apache.isis.metamodel.facets.actions.action;
 
 import java.lang.reflect.Method;
 
+import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.metamodel.facetapi.Facet;
 import org.apache.isis.metamodel.facets.AbstractFacetFactoryTest;
 import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
 import org.apache.isis.metamodel.facets.actions.action.semantics.ActionSemanticsFacetFallbackToNonIdempotent;
 import org.apache.isis.metamodel.facets.actions.semantics.ActionSemanticsFacet;
 
+import lombok.val;
+
 public class ActionSemanticsFacetFallbackToNonIdempotentFactoryTest extends AbstractFacetFactoryTest {
 
     private ActionAnnotationFacetFactory facetFactory;
+    
+    private void processSemantics(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processSemantics(processMethodContext, actionIfAny);
+    }
 
     @Override
     protected void setUp() throws Exception {
@@ -52,7 +61,7 @@ public class ActionSemanticsFacetFallbackToNonIdempotentFactoryTest extends Abst
         }
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processSemantics(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processSemantics(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(ActionSemanticsFacet.class);
         assertNotNull(facet);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java
index 7b880fd..4201bd2 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java
@@ -29,11 +29,19 @@ import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
 import org.apache.isis.metamodel.facets.actions.prototype.PrototypeFacet;
 import org.apache.isis.metamodel.facets.actions.prototype.PrototypeFacetAbstract;
 
+import lombok.val;
+
 public class PrototypeFacetAnnotationFactoryTest extends AbstractFacetFactoryTest {
 
     //private JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
 
     private ActionAnnotationFacetFactory facetFactory;
+    
+    private void processRestrictTo(
+            ActionAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
+        facetFactory.processRestrictTo(processMethodContext, actionIfAny);
+    }
 
     @Override
     protected void setUp() throws Exception {
@@ -56,7 +64,7 @@ public class PrototypeFacetAnnotationFactoryTest extends AbstractFacetFactoryTes
         }
         final Method actionMethod = findMethod(Customer.class, "someAction");
 
-        facetFactory.processRestrictTo(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processRestrictTo(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(PrototypeFacet.class);
         assertNotNull(facet);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/DisabledAnnotationOnPropertyFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/DisabledAnnotationOnPropertyFacetFactoryTest.java
index 7b8da49..56e07fb 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/DisabledAnnotationOnPropertyFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/DisabledAnnotationOnPropertyFacetFactoryTest.java
@@ -32,6 +32,8 @@ import org.apache.isis.metamodel.facets.members.disabled.DisabledFacetAbstract;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
+import lombok.val;
+
 public class DisabledAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFactoryTest {
 
     private PropertyAnnotationFacetFactory facetFactory;
@@ -48,6 +50,12 @@ public class DisabledAnnotationOnPropertyFacetFactoryTest extends AbstractFacetF
         facetFactory = null;
         super.tearDown();
     }
+    
+    private void processEditing(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processEditing(processMethodContext, propertyIfAny);
+    }
 
     public void testDisabledAnnotationPickedUpOnProperty() {
         class Customer {
@@ -58,7 +66,7 @@ public class DisabledAnnotationOnPropertyFacetFactoryTest extends AbstractFacetF
         }
         final Method actionMethod = findMethod(Customer.class, "getNumberOfOrders");
 
-        facetFactory.processEditing(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processEditing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(DisabledFacet.class);
         assertNotNull(facet);
@@ -79,7 +87,7 @@ public class DisabledAnnotationOnPropertyFacetFactoryTest extends AbstractFacetF
         }
         final Method actionMethod = findMethod(Customer.class, "getNumberOfOrders");
 
-        facetFactory.processEditing(new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
+        processEditing(facetFactory, new ProcessMethodContext(Customer.class, null, actionMethod, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(DisabledFacet.class);
         assertNotNull(facet);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/MandatoryAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/MandatoryAnnotationFacetFactoryTest.java
index 5e11fb5..21e7bbd 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/MandatoryAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/MandatoryAnnotationFacetFactoryTest.java
@@ -31,6 +31,8 @@ import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
 import org.apache.isis.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
 import org.apache.isis.metamodel.facets.properties.property.mandatory.MandatoryFacetForPropertyAnnotation;
 
+import lombok.val;
+
 public class MandatoryAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
 
     private PropertyAnnotationFacetFactory facetFactory;
@@ -42,6 +44,12 @@ public class MandatoryAnnotationFacetFactoryTest extends AbstractFacetFactoryTes
         facetFactory = new PropertyAnnotationFacetFactory();
     }
 
+    private void processOptional(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processOptional(processMethodContext, propertyIfAny);
+    }
+    
     public void testMandatoryAnnotationPickedUpOnProperty() {
 
         class Customer {
@@ -52,7 +60,7 @@ public class MandatoryAnnotationFacetFactoryTest extends AbstractFacetFactoryTes
         }
         final Method method = findMethod(Customer.class, "getFirstName");
 
-        facetFactory.processOptional(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processOptional(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(MandatoryFacet.class);
         assertNotNull(facet);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/NotPersistedAnnotationOnPropertyFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/NotPersistedAnnotationOnPropertyFacetFactoryTest.java
index 87bd7b8..5cba767 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/NotPersistedAnnotationOnPropertyFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/NotPersistedAnnotationOnPropertyFacetFactoryTest.java
@@ -29,6 +29,8 @@ import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
 import org.apache.isis.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
 import org.apache.isis.metamodel.facets.properties.property.notpersisted.NotPersistedFacetForPropertyAnnotation;
 
+import lombok.val;
+
 public class NotPersistedAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFactoryTest {
 
     private PropertyAnnotationFacetFactory facetFactory;
@@ -39,6 +41,12 @@ public class NotPersistedAnnotationOnPropertyFacetFactoryTest extends AbstractFa
         facetFactory = new PropertyAnnotationFacetFactory();
     }
 
+    private void processNotPersisted(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processNotPersisted(processMethodContext, propertyIfAny);
+    }
+    
     public void testAnnotationPickedUpOnProperty() {
 
         class Customer {
@@ -50,7 +58,7 @@ public class NotPersistedAnnotationOnPropertyFacetFactoryTest extends AbstractFa
         }
         final Method method = findMethod(Customer.class, "getFirstName");
 
-        facetFactory.processNotPersisted(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processNotPersisted(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(NotPersistedFacet.class);
         assertNotNull(facet);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
index 7613312..2b8cda5 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
@@ -43,6 +43,7 @@ import org.apache.isis.metamodel.facetapi.FacetHolder;
 import org.apache.isis.metamodel.facetapi.FacetUtil;
 import org.apache.isis.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.metamodel.facets.FacetFactory;
+import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
 import org.apache.isis.metamodel.facets.all.hide.HiddenFacet;
 import org.apache.isis.metamodel.facets.members.disabled.DisabledFacet;
 import org.apache.isis.metamodel.facets.object.domainobject.domainevents.PropertyDomainEventDefaultFacetForDomainObjectAnnotation;
@@ -79,6 +80,8 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import lombok.val;
+
 public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
 
     PropertyAnnotationFacetFactory facetFactory;
@@ -108,6 +111,56 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
 
         }});
     }
+    
+    private static void processModify(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processModify(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processHidden(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processHidden(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processOptional(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processOptional(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processRegEx(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processRegEx(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processEditing(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processEditing(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processMaxLength(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processMaxLength(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processMustSatisfy(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processMustSatisfy(processMethodContext, propertyIfAny);
+    }
+    
+    private static void processNotPersisted(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processNotPersisted(processMethodContext, propertyIfAny);
+    }
+    
+    
 
     @Before
     public void setUp() throws Exception {
@@ -192,7 +245,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processModify(processMethodContext);
+            processModify(facetFactory, processMethodContext);
 
             // then
             final PropertyDomainEventFacet domainEventFacet = facetedMethod.getFacet(PropertyDomainEventFacet.class);
@@ -250,7 +303,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processModify(processMethodContext);
+            processModify(facetFactory, processMethodContext);
 
             // then
             final Facet domainEventFacet = facetedMethod.getFacet(PropertyDomainEventFacet.class);
@@ -306,7 +359,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processModify(processMethodContext);
+            processModify(facetFactory, processMethodContext);
 
             // then
             final Facet domainEventFacet = facetedMethod.getFacet(PropertyDomainEventFacet.class);
@@ -357,7 +410,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processModify(processMethodContext);
+            processModify(facetFactory, processMethodContext);
 
             // then
             final Facet domainEventFacet = facetedMethod.getFacet(PropertyDomainEventFacet.class);
@@ -403,7 +456,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processHidden(processMethodContext);
+            processHidden(facetFactory, processMethodContext);
 
             // then
             final HiddenFacet hiddenFacet = facetedMethod.getFacet(HiddenFacet.class);
@@ -443,7 +496,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processEditing(processMethodContext);
+            processEditing(facetFactory, processMethodContext);
 
             // then
             final DisabledFacet disabledFacet = facetedMethod.getFacet(DisabledFacet.class);
@@ -478,7 +531,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processMaxLength(processMethodContext);
+            processMaxLength(facetFactory, processMethodContext);
 
             // then
             final MaxLengthFacet maxLengthFacet = facetedMethod.getFacet(MaxLengthFacet.class);
@@ -530,7 +583,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processMustSatisfy(processMethodContext);
+            processMustSatisfy(facetFactory, processMethodContext);
 
             // then
             final MustSatisfySpecificationFacet mustSatisfySpecificationFacet = facetedMethod.getFacet(MustSatisfySpecificationFacet.class);
@@ -567,7 +620,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processNotPersisted(processMethodContext);
+            processNotPersisted(facetFactory, processMethodContext);
 
             // then
             final NotPersistedFacet notPersistedFacet = facetedMethod.getFacet(NotPersistedFacet.class);
@@ -600,7 +653,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processOptional(processMethodContext);
+            processOptional(facetFactory, processMethodContext);
 
             // then
             final MandatoryFacet mandatoryFacet = facetedMethod.getFacet(MandatoryFacet.class);
@@ -629,7 +682,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processOptional(processMethodContext);
+            processOptional(facetFactory, processMethodContext);
 
             // then
             final MandatoryFacet mandatoryFacet = facetedMethod.getFacet(MandatoryFacet.class);
@@ -658,7 +711,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processOptional(processMethodContext);
+            processOptional(facetFactory, processMethodContext);
 
             // then
             final MandatoryFacet mandatoryFacet = facetedMethod.getFacet(MandatoryFacet.class);
@@ -685,7 +738,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processOptional(processMethodContext);
+            processOptional(facetFactory, processMethodContext);
 
             // then
             final MandatoryFacet mandatoryFacet = facetedMethod.getFacet(MandatoryFacet.class);
@@ -717,7 +770,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processRegEx(processMethodContext);
+            processRegEx(facetFactory, processMethodContext);
 
             // then
             final RegExFacet regExFacet = facetedMethod.getFacet(RegExFacet.class);
@@ -747,7 +800,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processRegEx(processMethodContext);
+            processRegEx(facetFactory, processMethodContext);
 
             // then
             final RegExFacet regExFacet = facetedMethod.getFacet(RegExFacet.class);
@@ -775,7 +828,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processRegEx(processMethodContext);
+            processRegEx(facetFactory, processMethodContext);
 
             // then
             final RegExFacet regExFacet = facetedMethod.getFacet(RegExFacet.class);
@@ -803,7 +856,7 @@ public class PropertyAnnotationFacetFactoryTest extends AbstractFacetFactoryJUni
             // when
             final FacetFactory.ProcessMethodContext processMethodContext = new FacetFactory.ProcessMethodContext(cls, null,
                     propertyMethod, mockMethodRemover, facetedMethod);
-            facetFactory.processRegEx(processMethodContext);
+            processRegEx(facetFactory, processMethodContext);
 
             // then
             final RegExFacet regExFacet = facetedMethod.getFacet(RegExFacet.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest.java
index a0ac052..c913e32 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest.java
@@ -32,6 +32,8 @@ import org.apache.isis.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
 import org.apache.isis.metamodel.facets.properties.property.mandatory.MandatoryFacetForPropertyAnnotation;
 import org.apache.isis.metamodel.facets.properties.property.mandatory.MandatoryFacetInvertedByNullableAnnotationOnProperty;
 
+import lombok.val;
+
 public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFactoryTest {
 
     private PropertyAnnotationFacetFactory facetFactory;
@@ -42,6 +44,12 @@ public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest e
         facetFactory = new PropertyAnnotationFacetFactory();
     }
 
+    private void processOptional(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processOptional(processMethodContext, propertyIfAny);
+    }
+    
     public void testPropertyAnnotationWithOptionalityPickedUpOnProperty() {
 
         class Customer {
@@ -52,7 +60,7 @@ public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest e
         }
         final Method method = findMethod(Customer.class, "getFirstName");
 
-        facetFactory.processOptional(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processOptional(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(MandatoryFacet.class);
         assertNotNull(facet);
@@ -62,7 +70,6 @@ public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest e
     public void testPropertyAnnotationIgnoredForPrimitiveOnProperty() {
 
         class Customer {
-            @SuppressWarnings("unused")
             @Property(optionality = Optionality.OPTIONAL)
             public int getNumberOfOrders() {
                 return 0;
@@ -70,7 +77,7 @@ public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest e
         }
         final Method method = findMethod(Customer.class, "getNumberOfOrders");
 
-        facetFactory.processOptional(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processOptional(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         assertNotNull(facetedMethod.getFacet(MandatoryFacet.class));
     }
@@ -85,7 +92,7 @@ public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest e
         }
         final Method method = findMethod(Customer.class, "getFirstName");
 
-        facetFactory.processOptional(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processOptional(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(MandatoryFacet.class);
         assertNotNull(facet);
@@ -103,7 +110,7 @@ public class PropertyOptionalityOrNullableAnnotationOnPropertyFacetFactoryTest e
         }
         final Method method = findMethod(Customer.class, "getNumberOfOrders");
 
-        facetFactory.processOptional(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processOptional(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         assertNull(facetedMethod.getFacet(MandatoryFacet.class));
     }
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/RegExAnnotationOnPropertyFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/RegExAnnotationOnPropertyFacetFactoryTest.java
index 5202982..0e2a6be 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/RegExAnnotationOnPropertyFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/properties/property/RegExAnnotationOnPropertyFacetFactoryTest.java
@@ -25,12 +25,15 @@ import javax.validation.constraints.Pattern;
 
 import org.junit.Before;
 
+import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.metamodel.facetapi.Facet;
 import org.apache.isis.metamodel.facets.AbstractFacetFactoryTest;
 import org.apache.isis.metamodel.facets.FacetFactory.ProcessMethodContext;
 import org.apache.isis.metamodel.facets.objectvalue.regex.RegExFacet;
 import org.apache.isis.metamodel.facets.properties.property.regex.RegExFacetForPatternAnnotationOnProperty;
 
+import lombok.val;
+
 public class RegExAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFactoryTest {
 
     private PropertyAnnotationFacetFactory facetFactory;
@@ -42,10 +45,15 @@ public class RegExAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFact
         facetFactory = new PropertyAnnotationFacetFactory();
     }
 
+    private void processRegEx(
+            PropertyAnnotationFacetFactory facetFactory, ProcessMethodContext processMethodContext) {
+        val propertyIfAny = processMethodContext.synthesizeOnMethod(Property.class);
+        facetFactory.processRegEx(processMethodContext, propertyIfAny);
+    }
+    
     public void testRegExAnnotationPickedUpOnProperty() {
 
         class Customer {
-            @SuppressWarnings("unused")
             @Pattern(regexp = "^A.*", flags = { Pattern.Flag.CASE_INSENSITIVE })
             public String getFirstName() {
                 return null;
@@ -53,7 +61,7 @@ public class RegExAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFact
         }
         final Method method = findMethod(Customer.class, "getFirstName");
 
-        facetFactory.processRegEx(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processRegEx(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         final Facet facet = facetedMethod.getFacet(RegExFacet.class);
         assertNotNull(facet);
@@ -73,7 +81,7 @@ public class RegExAnnotationOnPropertyFacetFactoryTest extends AbstractFacetFact
         }
         final Method method = findMethod(Customer.class, "getNumberOfOrders");
 
-        facetFactory.processRegEx(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
+        processRegEx(facetFactory, new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
 
         assertNull(facetedMethod.getFacet(RegExFacet.class));
     }
diff --git a/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java b/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java
index 7705807..9f3f7a0 100644
--- a/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java
+++ b/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java
@@ -29,6 +29,7 @@ public class ProperActionSupport_action {
     private final ProperActionSupport holder;
 
     // proper mix-in action
+    //@Action // <-- inferred by annotation on type above
     public ProperActionSupport act() {
         return holder;
     }
diff --git a/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java b/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_property.java
similarity index 77%
copy from examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java
copy to examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_property.java
index 7705807..722337e 100644
--- a/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_action.java
+++ b/examples/smoketests/src/main/java/org/apache/isis/testdomain/model/good/ProperActionSupport_property.java
@@ -18,19 +18,20 @@
  */
 package org.apache.isis.testdomain.model.good;
 
-import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.Model;
+import org.apache.isis.applib.annotation.Property;
 
 import lombok.RequiredArgsConstructor;
 
-@Action @RequiredArgsConstructor
-public class ProperActionSupport_action {
+@Property @RequiredArgsConstructor
+public class ProperActionSupport_property {
     
     private final ProperActionSupport holder;
 
-    // proper mix-in action
-    public ProperActionSupport act() {
-        return holder;
+    //@Action(semantics=SAFE)   // <-- inferred (required)
+    //@ActionLayout(contributed=ASSOCIATION)  // <-- inferred (required)
+    public String prop() {
+        return holder.toString();
     }
     
     // proper support
diff --git a/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java b/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
index b93ec26..87f83a6 100644
--- a/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
+++ b/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
@@ -89,6 +89,9 @@ class DomainModelTest_usingGoodDomain {
         
         val oa_action = holderSpec.getObjectAction("action"); // proper mix-in support
         assertNotNull(oa_action);
+        
+        val oa_property = holderSpec.getAssociation("property"); // proper mix-in support
+        assertNotNull(oa_property);
     }