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

[isis] branch master updated: ISIS-2774: method finder overhaul (9)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new d9f06a8  ISIS-2774: method finder overhaul (9)
d9f06a8 is described below

commit d9f06a89561f0cd5fe982ab2b78217285eda94ad
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 8 17:12:29 2021 +0200

    ISIS-2774: method finder overhaul (9)
---
 .../isis/commons/internal/reflection/_Reflect.java |  10 +
 .../isis/core/metamodel/facets/ActionSupport.java  |  18 +-
 .../facets/HasPostConstructMethodCache.java        |   6 +-
 .../core/metamodel/facets/ParameterSupport.java    |  14 +-
 .../ActionValidationFacetViaMethodFactory.java     |   8 +-
 .../DescribedAsFacetForMemberViaMethodFactory.java |   6 +-
 .../DisableForContextFacetViaMethodFactory.java    |   6 +-
 .../HideForContextFacetViaMethodFactory.java       |   6 +-
 .../NamedFacetForMemberViaMethodFactory.java       |   6 +-
 .../support/MemberSupportFacetFactoryAbstract.java |   6 +-
 .../object/callbacks/CallbackFacetFactory.java     |   4 +-
 .../choices/enums/EnumValueSemanticsProvider.java  |   6 +-
 .../object/support/ObjectSupportFacetFactory.java  |   6 +-
 .../PropertyAutoCompleteFacetMethodFactory.java    |   6 +-
 .../PropertyChoicesFacetViaMethodFactory.java      |   6 +-
 .../PropertyDefaultFacetViaMethodFactory.java      |   6 +-
 .../update/PropertySetterFacetFactory.java         |   4 +-
 .../PropertyValidateFacetViaMethodFactory.java     |   6 +-
 .../isis/core/metamodel/methods/MethodFinder.java  | 265 +++++++++++++++++--
 .../metamodel/methods/MethodFinderOptions.java     | 281 ---------------------
 .../core/metamodel/methods/MethodFinderPAT.java    |  15 +-
 .../restfulobjects/viewer/mappers/FailureUtil.java |  34 ++-
 22 files changed, 323 insertions(+), 402 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java b/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
index 9dbcbd1..45e78e3 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
@@ -564,6 +564,15 @@ public final class _Reflect {
     @UtilityClass
     public static class Filter {
 
+        public static Predicate<Method> hasReturnType(final Class<?> expectedReturnType) {
+            return method->expectedReturnType.isAssignableFrom(method.getReturnType());
+        }
+
+        public static Predicate<Method> hasReturnTypeAnyOf(final Can<Class<?>> allowedReturnTypes) {
+            return method->allowedReturnTypes.stream()
+                    .anyMatch(allowedReturnType->allowedReturnType.isAssignableFrom(method.getReturnType()));
+        }
+
         public static Predicate<Executable> isPublic() {
             return ex->Modifier.isPublic(ex.getModifiers());
         }
@@ -576,6 +585,7 @@ public final class _Reflect {
             return ex->ex.getParameterTypes()[paramIndex].isAssignableFrom(paramType);
         }
 
+        //TODO simple array compare should do
         public static Predicate<Executable> paramSignatureMatch(final Class<?>[] matchingParamTypes) {
             return ex->{
                 // check params (if required)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java
index 264a876..75f6ae3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java
@@ -29,8 +29,7 @@ import org.springframework.lang.Nullable;
 
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.collections._Arrays;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 import org.apache.isis.core.metamodel.methods.MethodFinderPAT;
 import org.apache.isis.core.metamodel.methods.MethodFinderPAT.MethodAndPatConstructor;
 
@@ -48,12 +47,9 @@ public final class ActionSupport {
     public static class ActionSupportingMethodSearchRequest {
 
         @NonNull FacetFactory.ProcessMethodContext processMethodContext;
-        @Getter @NonNull MethodFinderOptions finderOptions;
+        @Getter @NonNull MethodFinder methodFinder;
         @NonNull EnumSet<SearchAlgorithm> searchAlgorithms;
 
-        @Deprecated
-        @NonNull ReturnTypePattern returnTypePattern;
-
         Class<?> additionalParamType;
 
         @Getter(lazy = true)
@@ -107,14 +103,12 @@ public final class ActionSupport {
             final Consumer<ActionSupportingMethodSearchResult> onMethodFound) {
 
         val paramTypes = searchRequest.getParamTypes();
-        val finderOptions = searchRequest.getFinderOptions();
+        val finderOptions = searchRequest.getMethodFinder();
         val additionalParamTypes = Can.ofNullable(searchRequest.getAdditionalParamType());
-        val anyOfReturnTypes = searchRequest.getReturnTypePattern().matchingTypes(void.class); // ignores actual type
 
         MethodFinderPAT
-        .findMethodWithPATArg_returningAnyOf(
+        .findMethodWithPATArg(
                 finderOptions,
-                anyOfReturnTypes,
                 paramTypes, additionalParamTypes)
         .map(ActionSupport::toSearchResult)
         .forEach(onMethodFound);
@@ -134,7 +128,7 @@ public final class ActionSupport {
             final Consumer<ActionSupportingMethodSearchResult> onMethodFound) {
 
         val paramTypes = searchRequest.getParamTypes();
-        val finderOptions = searchRequest.getFinderOptions();
+        val finderOptions = searchRequest.getMethodFinder();
 
         val additionalParamType = searchRequest.getAdditionalParamType();
         val additionalParamCount = additionalParamType!=null ? 1 : 0;
@@ -143,10 +137,8 @@ public final class ActionSupport {
         if(paramsConsideredCount>=0) {
 
             val signature = concat(paramTypes, paramsConsideredCount, additionalParamType);
-            val anyOfReturnTypes = searchRequest.getReturnTypePattern().matchingTypes(void.class); // ignores actual type
 
             finderOptions
-            .withReturnTypeAnyOf(anyOfReturnTypes)
             .streamMethodsMatchingSignature(signature)
             .map(ActionSupport::toSearchResult)
             .forEach(onMethodFound);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java
index 1812557..2ce3d4e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java
@@ -24,7 +24,7 @@ import java.lang.reflect.Method;
 import javax.annotation.PostConstruct;
 
 import org.apache.isis.core.metamodel.methods.MethodByClassMap;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.val;
 
@@ -38,14 +38,14 @@ public interface HasPostConstructMethodCache {
     default Method postConstructMethodFor(final Object pojo) {
         return findAnnotatedMethod(
                 // @PostConstruct is allowed to appear on non-public methods
-                MethodFinderOptions.notNecessarilyPublic(pojo.getClass(), MethodFinderOptions.ANY_NAME)
+                MethodFinder.notNecessarilyPublic(pojo.getClass(), MethodFinder.ANY_NAME)
                 .withRequiredReturnType(void.class),
                 PostConstruct.class,
                 getPostConstructMethodsCache());
     }
 
     private static Method findAnnotatedMethod(
-            final MethodFinderOptions options,
+            final MethodFinder options,
             final Class<? extends Annotation> annotationClass,
             final MethodByClassMap methods) {
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java
index c402034..8c9f59b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java
@@ -31,7 +31,7 @@ import org.springframework.lang.Nullable;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.collections._Arrays;
 import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 import org.apache.isis.core.metamodel.methods.MethodFinderPAT;
 import org.apache.isis.core.metamodel.methods.MethodFinderPAT.MethodAndPatConstructor;
 
@@ -132,10 +132,10 @@ public final class ParameterSupport {
         val additionalParamTypes = Can.ofNullable(searchRequest.getAdditionalParamType());
 
         MethodFinderPAT
-        .findMethodWithPATArg_returningAnyOf(
-                MethodFinderOptions
-                .memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy()),
-                searchRequest.getReturnTypePattern().matchingTypes(paramType),
+        .findMethodWithPATArg(
+                MethodFinder
+                .memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy())
+                .withReturnTypeAnyOf(searchRequest.getReturnTypePattern().matchingTypes(paramType)),
                 paramTypes, additionalParamTypes)
         .map(methodAndPatConstructor->toSearchResult(paramIndex, paramType, methodAndPatConstructor))
         .forEach(onMethodFound);
@@ -164,7 +164,7 @@ public final class ParameterSupport {
         val paramType = paramTypes[paramIndex];
         val signature = new Class<?>[]{paramType};
 
-        MethodFinderOptions
+        MethodFinder
         .memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy())
         .withReturnTypeAnyOf(searchRequest.getReturnTypePattern().matchingTypes(paramType))
         .streamMethodsMatchingSignature(signature)
@@ -194,7 +194,7 @@ public final class ParameterSupport {
             val signature = concat(paramTypes, paramsConsideredCount, additionalParamType);
 
             val supportingMethod =
-            MethodFinderOptions
+            MethodFinder
             .memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy())
             .withReturnTypeAnyOf(searchRequest.getReturnTypePattern().matchingTypes(paramType))
             .streamMethodsMatchingSignature(signature)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
index 7d30916..e971ba2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
@@ -23,14 +23,13 @@ import java.util.EnumSet;
 import javax.inject.Inject;
 
 import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSupportPrefix;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.ActionSupport;
 import org.apache.isis.core.metamodel.facets.ActionSupport.SearchAlgorithm;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.param.validate.method.ActionParameterValidationFacetViaMethod;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.val;
 
@@ -48,12 +47,11 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
         val searchRequest = ActionSupport.ActionSupportingMethodSearchRequest.builder()
                 .processMethodContext(processMethodContext)
-                .returnTypePattern(ReturnTypePattern.TEXT)
-                .finderOptions(methodFinderOptions)
+                .methodFinder(methodFinder)
                 .searchAlgorithms(EnumSet.of(SearchAlgorithm.PAT, SearchAlgorithm.ALL_PARAM_TYPES))
                 .build();
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java
index d781ceb..392605e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 public class DescribedAsFacetForMemberViaMethodFactory
 extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(NO_ARG)
         .peek(processMethodContext::removeMethod)
         .forEach(describedMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
index 06d85d8..0fd8ece 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 public class DisableForContextFacetViaMethodFactory
 extends MemberSupportFacetFactoryAbstract  {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract  {
      @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
-         methodFinderOptions
+         methodFinder
          .streamMethodsMatchingSignature(NO_ARG)
          .peek(processMethodContext::removeMethod)
          .forEach(disableMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java
index 50af462..e80d19a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 public class HideForContextFacetViaMethodFactory
 extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(NO_ARG)
         .peek(processMethodContext::removeMethod)
         .forEach(hideMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java
index fbc9396..952042d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 public class NamedFacetForMemberViaMethodFactory
 extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(NO_ARG)
         .peek(processMethodContext::removeMethod)
         .forEach(namedMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java
index b263104..858e9a3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java
@@ -22,7 +22,7 @@ import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSupportPrefix;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.NonNull;
 import lombok.val;
@@ -69,7 +69,7 @@ extends MemberAndPropertySupportFacetFactoryAbstract {
                 .flatMap(processMethodContext::memberSupportCandidates);
 
         search(processMethodContext,
-                MethodFinderOptions
+                MethodFinder
                 .memberSupport(processMethodContext.getCls(),
                         methodNameCandidates,
                         processMethodContext.getIntrospectionPolicy())
@@ -80,6 +80,6 @@ extends MemberAndPropertySupportFacetFactoryAbstract {
 
     protected abstract void search(
             ProcessMethodContext processMethodContext,
-            MethodFinderOptions methodFinderOptions);
+            MethodFinder methodFinder);
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java
index f94896c..76fd7aa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java
@@ -29,7 +29,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.CallbackM
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 import org.apache.isis.core.metamodel.methods.MethodPrefixBasedFacetFactoryAbstract;
 
 import lombok.val;
@@ -66,7 +66,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
 
         val callbackMethods =
 
-        MethodFinderOptions
+        MethodFinder
         .livecycleCallback(
                 cls,
                 callbackMethodEnum.getMethodNames(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
index 33f337e..febcde9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
@@ -31,7 +31,7 @@ import org.apache.isis.core.metamodel.commons.MethodExtensions;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueSemanticsProviderAndFacetAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.val;
 
@@ -82,13 +82,13 @@ implements EnumFacet {
 
         titleMethod =
 
-        MethodFinderOptions
+        MethodFinder
         .objectSupport(
                 getAdaptedClass(),
                 supportMethodEnum.getMethodNames(),
                 introspectionPolicy)
         .withReturnTypeAnyOf(supportMethodEnum.getReturnTypeCategory().getReturnTypes())
-        .streamMethodsMatchingSignature(MethodFinderOptions.NO_ARG)
+        .streamMethodsMatchingSignature(MethodFinder.NO_ARG)
         .findFirst()
         .orElse(null);
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java
index 794e892..2b527a6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java
@@ -43,7 +43,7 @@ import org.apache.isis.core.metamodel.facets.object.icon.method.IconFacetViaIcon
 import org.apache.isis.core.metamodel.facets.object.layout.LayoutFacetViaLayoutMethod;
 import org.apache.isis.core.metamodel.facets.object.title.methods.TitleFacetInferredFromToStringMethod;
 import org.apache.isis.core.metamodel.facets.object.title.methods.TitleFacetViaTitleMethod;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 import org.apache.isis.core.metamodel.methods.MethodPrefixBasedFacetFactoryAbstract;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
@@ -111,7 +111,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
 
         val toString = ObjectSupportMethod.TO_STRING;
 
-        MethodFinderOptions
+        MethodFinder
         .publicOnly(
                 processClassContext.getCls(),
                 toString.getMethodNames())
@@ -131,7 +131,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
             final BiFunction<Method, FacetHolder, Optional<? extends Facet>> ojectSupportFacetConstructor) {
 
 
-        MethodFinderOptions
+        MethodFinder
         .objectSupport(
                 processClassContext.getCls(),
                 objectSupportMethodEnum.getMethodNames(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
index 8ff0d19..630a817 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.val;
 
@@ -39,12 +39,12 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
         val getterOrMixinMain = processMethodContext.getMethod();
         val getterType = getterOrMixinMain.getReturnType();
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(STRING_ARG)
         .peek(processMethodContext::removeMethod)
         .forEach(autoCompleteMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
index 992d520..4223af4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.val;
 
@@ -39,12 +39,12 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
         val getterOrMixinMain = processMethodContext.getMethod();
         val getterType = getterOrMixinMain.getReturnType();
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(NO_ARG)
         .peek(processMethodContext::removeMethod)
         .forEach(choicesMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java
index 95893e3..c1f530f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 public class PropertyDefaultFacetViaMethodFactory
 extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(NO_ARG)
         .peek(processMethodContext::removeMethod)
         .forEach(defaultMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java
index 5bfc1eb..40b304b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java
@@ -32,7 +32,7 @@ import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyClearFacetViaSetterMethod;
 import org.apache.isis.core.metamodel.facets.properties.update.init.PropertyInitializationFacetViaSetterMethod;
 import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacetViaSetterMethod;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 import org.apache.isis.core.metamodel.methods.MethodPrefixBasedFacetFactoryAbstract;
 
 import lombok.val;
@@ -61,7 +61,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
         final Class<?>[] signature = new Class[] { getterMethod.getReturnType() };
 
         val setterMethods =
-        MethodFinderOptions
+        MethodFinder
         .accessor(processMethodContext.getCls(), methodNameCandidates, processMethodContext.getIntrospectionPolicy())
         .withReturnTypeAnyOf(ReturnTypeCategory.VOID.getReturnTypes())
         .streamMethodsMatchingSignature(signature)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
index f24184a..0da1927 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
 
 import lombok.val;
 
@@ -39,12 +39,12 @@ extends MemberSupportFacetFactoryAbstract  {
     @Override
     protected void search(
             final ProcessMethodContext processMethodContext,
-            final MethodFinderOptions methodFinderOptions) {
+            final MethodFinder methodFinder) {
 
         val getterMethod = processMethodContext.getMethod();
         val argType = getterMethod.getReturnType();
 
-        methodFinderOptions
+        methodFinder
         .streamMethodsMatchingSignature(new Class[] { argType })
         .peek(processMethodContext::removeMethod)
         .forEach(validateMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java
index 3fe0385..aeb95a3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java
@@ -18,44 +18,263 @@
  */
 package org.apache.isis.core.metamodel.methods;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
+import org.springframework.lang.Nullable;
+
+import org.apache.isis.applib.annotation.Domain;
+import org.apache.isis.applib.annotation.Introspection.EncapsulationPolicy;
+import org.apache.isis.applib.annotation.Introspection.IntrospectionPolicy;
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.commons.internal.functions._Predicates;
+import org.apache.isis.commons.internal.reflection._Annotations;
+import org.apache.isis.commons.internal.reflection._ClassCache;
+import org.apache.isis.commons.internal.reflection._Reflect;
+import org.apache.isis.core.config.progmodel.ProgrammingModelConstants;
+import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ConflictingAnnotations;
+import org.apache.isis.core.metamodel.commons.MethodUtil;
 
-/**
- * Support of multiple concurrent naming conventions.
- */
-//@Log4j2
-public final class MethodFinder {
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public class MethodFinder {
+
+    public static MethodFinder of(
+            final @NonNull Class<?> correspondingClass,
+            final @NonNull Can<String> methodNameCandidatesPossiblyDuplicated,
+            final @NonNull EncapsulationPolicy encapsulationPolicy,
+            final @NonNull Predicate<Method> mustSatisfy) {
+
+        final Predicate<Method> isNotStatic = MethodUtil::isNotStatic;
+        val methodNameCandidates = methodNameCandidatesPossiblyDuplicated.distinct();
+
+        return new MethodFinder(
+                correspondingClass,
+                encapsulationPolicy,
+                methodNameCandidates.equals(ANY_NAME)
+                        ? isNotStatic.and(mustSatisfy)
+                        : isNotStatic
+                            .and(method->methodNameCandidates.contains(method.getName()))
+                            .and(mustSatisfy),
+                methodNameCandidates);
+    }
+
+    public static final Can<String> ANY_NAME = Can.of(""); // arbitrary marker
+    public static final Class<?>[] NO_ARG = new Class<?>[0];
+
+    public static MethodFinder notNecessarilyPublic(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates) {
+        return of(
+                correspondingClass,
+                methodNameCandidates,
+                EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
+                _Predicates.alwaysTrue()
+                );
+    }
+
+    public static MethodFinder publicOnly(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates) {
+        return of(
+                correspondingClass,
+                methodNameCandidates,
+                EncapsulationPolicy.ONLY_PUBLIC_MEMBERS_SUPPORTED,
+                _Predicates.alwaysTrue()
+                );
+    }
+
+    public static MethodFinder accessor(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates,
+            final IntrospectionPolicy memberIntrospectionPolicy) {
+        return havingAnyOrNoAnnotation(
+                correspondingClass,
+                methodNameCandidates,
+                memberIntrospectionPolicy);
+    }
+
+    public static MethodFinder objectSupport(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates,
+            final IntrospectionPolicy memberIntrospectionPolicy) {
+        return supportMethod(
+                correspondingClass,
+                methodNameCandidates,
+                memberIntrospectionPolicy,
+                Domain.Include.class,
+                ProgrammingModelConstants.ConflictingAnnotations.OBJECT_SUPPORT);
+    }
+
+    public static MethodFinder livecycleCallback(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates,
+            final IntrospectionPolicy memberIntrospectionPolicy) {
+        return supportMethod(
+                correspondingClass,
+                methodNameCandidates,
+                memberIntrospectionPolicy,
+                Domain.Include.class,
+                ProgrammingModelConstants.ConflictingAnnotations.OBJECT_LIFECYCLE);
+    }
+
+    public static MethodFinder memberSupport(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates,
+            final IntrospectionPolicy memberIntrospectionPolicy) {
+        return supportMethod(
+                correspondingClass,
+                methodNameCandidates,
+                memberIntrospectionPolicy,
+                Domain.Include.class,
+                ProgrammingModelConstants.ConflictingAnnotations.MEMBER_SUPPORT);
+    }
+
+    @Getter private final @NonNull Class<?> correspondingClass;
+    @Getter private final @NonNull EncapsulationPolicy encapsulationPolicy;
+    @Getter private final @NonNull Predicate<Method> mustSatisfy;
+    private final @NonNull Can<String> methodNameCandidates;
+
+    public Stream<Method> streamMethodsMatchingSignature(
+            final @Nullable Class<?>[] paramTypes) {
+
+        if(paramTypes==null) {
+            return streamMethodsIgnoringSignature();
+        }
+
+        val type = getCorrespondingClass();
+        val classCache = _ClassCache.getInstance();
+        val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
 
-    public static Predicate<Method> hasReturnType(final Class<?> expectedReturnType) {
-        return method->expectedReturnType.isAssignableFrom(method.getReturnType());
+        if(methodNameCandidates.equals(ANY_NAME)) {
+            //stream all
+            return (isEncapsulationSupported
+                    ? classCache.streamPublicOrDeclaredMethods(type)
+                    : classCache.streamPublicMethods(type))
+                        .filter(method->Arrays.equals(paramTypes, method.getParameterTypes()))
+                        .filter(mustSatisfy);
+        }
+
+        return methodNameCandidates.stream()
+        .map(name->isEncapsulationSupported
+                ? classCache.lookupPublicOrDeclaredMethod(type, name, paramTypes)
+                : classCache.lookupPublicMethod(type, name, paramTypes))
+        .filter(_NullSafe::isPresent)
+        .filter(mustSatisfy);
+
+    }
+
+    public Stream<Method> streamMethodsIgnoringSignature() {
+        val type = getCorrespondingClass();
+        val classCache = _ClassCache.getInstance();
+        val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
+        return (isEncapsulationSupported
+                ? classCache.streamPublicOrDeclaredMethods(type)
+                : classCache.streamPublicMethods(type))
+                    .filter(mustSatisfy);
+    }
+
+    // -- WITHERS
+
+    public MethodFinder withRequiredReturnType(final @NonNull Class<?> requiredReturnType) {
+        return new MethodFinder(
+                correspondingClass,
+                encapsulationPolicy,
+                mustSatisfy.and(_Reflect.Filter.hasReturnType(requiredReturnType)),
+                methodNameCandidates);
+    }
+
+    public MethodFinder withReturnTypeAnyOf(final @NonNull Can<Class<?>> anyOfReturnTypes) {
+        return new MethodFinder(
+                correspondingClass,
+                encapsulationPolicy,
+                mustSatisfy.and(_Reflect.Filter.hasReturnTypeAnyOf(anyOfReturnTypes)),
+                methodNameCandidates);
+    }
+
+
+    // -- HELPER
+
+    private static MethodFinder havingAnyOrNoAnnotation(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates,
+            final IntrospectionPolicy memberIntrospectionPolicy) {
+        return of(
+                correspondingClass,
+                methodNameCandidates,
+                memberIntrospectionPolicy.getEncapsulationPolicy(),
+                _Predicates.alwaysTrue());
     }
 
-    public static Predicate<Method> hasReturnTypeAnyOf(final Can<Class<?>> allowedReturnTypes) {
-        return method->allowedReturnTypes.stream()
-                .anyMatch(allowedReturnType->allowedReturnType.isAssignableFrom(method.getReturnType()));
+    private static MethodFinder supportMethod(
+            final Class<?> correspondingClass,
+            final Can<String> methodNameCandidates,
+            final IntrospectionPolicy memberIntrospectionPolicy,
+            final Class<? extends Annotation> annotationType,
+            final ConflictingAnnotations conflictingAnnotations) {
+
+        return of(
+                correspondingClass,
+                methodNameCandidates,
+                // support methods are always allowed private
+                EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
+                havingAnnotationIfEnforcedByPolicyOrAccessibility(
+                        memberIntrospectionPolicy,
+                        annotationType,
+                        conflictingAnnotations.getProhibits()));
+
     }
 
-    public static Stream<Method> findMethod(
-            final MethodFinderOptions options,
-            final Class<?>[] signature) {
-        return options.streamMethodsMatchingSignature(signature);
+    private static Predicate<Method> havingAnnotationIfEnforcedByPolicyOrAccessibility(
+            final IntrospectionPolicy memberIntrospectionPolicy,
+            final Class<? extends Annotation> annotationType,
+            final Can<Class<? extends Annotation>> conflictingAnnotations) {
+
+        //MemberAnnotationPolicy
+        //  when REQUIRED -> annot. on support also required
+        //  when OPTIONAL -> annot. on support only required when support method is private
+
+        return memberIntrospectionPolicy.getMemberAnnotationPolicy().isMemberAnnotationsRequired()
+                    ? method->havingAnnotation(method, annotationType, conflictingAnnotations)
+                    : method-> !_Reflect.isAccessible(method)
+                            ? havingAnnotation(method, annotationType, conflictingAnnotations)
+                            : true;
+
     }
 
-    // -- SEARCH FOR MULTIPLE NAME CANDIDATES
+    //FIXME[ISIS-2774] if annotation appears on an abstract method that was inherited with given method,
+    // its not detected here
+    private static boolean havingAnnotation(
+            final Method method,
+            final Class<? extends Annotation> annotationType,
+            final Can<Class<? extends Annotation>> conflictingAnnotations) {
 
-    @Deprecated
-    public static Stream<Method> findMethod_returningAnyOf(
-            final MethodFinderOptions options,
-            final Can<Class<?>> anyOfReturnTypes,
-            final Class<?>[] signature) {
+        val isMarkerAnnotationPresent = _Annotations.synthesizeInherited(method, annotationType).isPresent();
+        if(isMarkerAnnotationPresent) {
 
-        return options
-                .withReturnTypeAnyOf(anyOfReturnTypes)
-                .streamMethodsMatchingSignature(signature);
+            val isConflictingAnnotationPresent = conflictingAnnotations
+            .stream()
+            .anyMatch(conflictingAnnotationType->
+                    _Annotations.synthesizeInherited(method, conflictingAnnotationType).isPresent());
+
+            // do not pickup this method if conflicting - so meta-model validation will fail later on
+            return !isConflictingAnnotationPresent;
+        }
+        return isMarkerAnnotationPresent;
     }
 
+
+
+
+
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java
deleted file mode 100644
index 355fa82..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.methods;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-import org.springframework.lang.Nullable;
-
-import org.apache.isis.applib.annotation.Domain;
-import org.apache.isis.applib.annotation.Introspection.EncapsulationPolicy;
-import org.apache.isis.applib.annotation.Introspection.IntrospectionPolicy;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.commons.internal.functions._Predicates;
-import org.apache.isis.commons.internal.reflection._Annotations;
-import org.apache.isis.commons.internal.reflection._ClassCache;
-import org.apache.isis.commons.internal.reflection._Reflect;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ConflictingAnnotations;
-import org.apache.isis.core.metamodel.commons.MethodUtil;
-
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-
-@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
-public class MethodFinderOptions {
-
-    public static MethodFinderOptions of(
-            final @NonNull Class<?> correspondingClass,
-            final @NonNull Can<String> methodNameCandidatesPossiblyDuplicated,
-            final @NonNull EncapsulationPolicy encapsulationPolicy,
-            final @NonNull Predicate<Method> mustSatisfy) {
-
-        final Predicate<Method> isNotStatic = MethodUtil::isNotStatic;
-        val methodNameCandidates = methodNameCandidatesPossiblyDuplicated.distinct();
-
-        return new MethodFinderOptions(
-                correspondingClass,
-                encapsulationPolicy,
-                methodNameCandidates.equals(ANY_NAME)
-                        ? isNotStatic.and(mustSatisfy)
-                        : isNotStatic
-                            .and(method->methodNameCandidates.contains(method.getName()))
-                            .and(mustSatisfy),
-                methodNameCandidates);
-    }
-
-    public static final Can<String> ANY_NAME = Can.of(""); // arbitrary marker
-    public static final Class<?>[] NO_ARG = new Class<?>[0];
-    //private static final Class<?>[] ANY_ARG = new Class<?>[] {void.class}; // arbitrary marker
-
-    public static MethodFinderOptions notNecessarilyPublic(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates) {
-        return of(
-                correspondingClass,
-                methodNameCandidates,
-                EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
-                _Predicates.alwaysTrue()
-                );
-    }
-
-    public static MethodFinderOptions publicOnly(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates) {
-        return of(
-                correspondingClass,
-                methodNameCandidates,
-                EncapsulationPolicy.ONLY_PUBLIC_MEMBERS_SUPPORTED,
-                _Predicates.alwaysTrue()
-                );
-    }
-
-    public static MethodFinderOptions accessor(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates,
-            final IntrospectionPolicy memberIntrospectionPolicy) {
-        return havingAnyOrNoAnnotation(
-                correspondingClass,
-                methodNameCandidates,
-                memberIntrospectionPolicy);
-    }
-
-    public static MethodFinderOptions objectSupport(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates,
-            final IntrospectionPolicy memberIntrospectionPolicy) {
-        return supportMethod(
-                correspondingClass,
-                methodNameCandidates,
-                memberIntrospectionPolicy,
-                Domain.Include.class,
-                ProgrammingModelConstants.ConflictingAnnotations.OBJECT_SUPPORT);
-    }
-
-    public static MethodFinderOptions livecycleCallback(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates,
-            final IntrospectionPolicy memberIntrospectionPolicy) {
-        return supportMethod(
-                correspondingClass,
-                methodNameCandidates,
-                memberIntrospectionPolicy,
-                Domain.Include.class,
-                ProgrammingModelConstants.ConflictingAnnotations.OBJECT_LIFECYCLE);
-    }
-
-    public static MethodFinderOptions memberSupport(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates,
-            final IntrospectionPolicy memberIntrospectionPolicy) {
-        return supportMethod(
-                correspondingClass,
-                methodNameCandidates,
-                memberIntrospectionPolicy,
-                Domain.Include.class,
-                ProgrammingModelConstants.ConflictingAnnotations.MEMBER_SUPPORT);
-    }
-
-    @Getter private final @NonNull Class<?> correspondingClass;
-    @Getter private final @NonNull EncapsulationPolicy encapsulationPolicy;
-    @Getter private final @NonNull Predicate<Method> mustSatisfy;
-    private final @NonNull Can<String> methodNameCandidates;
-
-    public Stream<Method> streamMethodsMatchingSignature(
-            final @Nullable Class<?>[] paramTypes) {
-
-        if(paramTypes==null) {
-            return streamMethodsIgnoringSignature();
-        }
-
-        val type = getCorrespondingClass();
-        val classCache = _ClassCache.getInstance();
-        val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
-
-        if(methodNameCandidates.equals(ANY_NAME)) {
-            //stream all
-            return (isEncapsulationSupported
-                    ? classCache.streamPublicOrDeclaredMethods(type)
-                    : classCache.streamPublicMethods(type))
-                        .filter(method->Arrays.equals(paramTypes, method.getParameterTypes()))
-                        .filter(mustSatisfy);
-        }
-
-        return methodNameCandidates.stream()
-        .map(name->isEncapsulationSupported
-                ? classCache.lookupPublicOrDeclaredMethod(type, name, paramTypes)
-                : classCache.lookupPublicMethod(type, name, paramTypes))
-        .filter(_NullSafe::isPresent)
-        .filter(mustSatisfy);
-
-    }
-
-    public Stream<Method> streamMethodsIgnoringSignature() {
-        val type = getCorrespondingClass();
-        val classCache = _ClassCache.getInstance();
-        val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
-        return (isEncapsulationSupported
-                ? classCache.streamPublicOrDeclaredMethods(type)
-                : classCache.streamPublicMethods(type))
-                    .filter(mustSatisfy);
-    }
-
-    // -- WITHERS
-
-    public MethodFinderOptions withRequiredReturnType(final @NonNull Class<?> requiredReturnType) {
-        return new MethodFinderOptions(
-                correspondingClass,
-                encapsulationPolicy,
-                mustSatisfy.and(MethodFinder.hasReturnType(requiredReturnType)),
-                methodNameCandidates);
-    }
-
-    public MethodFinderOptions withReturnTypeAnyOf(final @NonNull Can<Class<?>> anyOfReturnTypes) {
-        return new MethodFinderOptions(
-                correspondingClass,
-                encapsulationPolicy,
-                mustSatisfy.and(MethodFinder.hasReturnTypeAnyOf(anyOfReturnTypes)),
-                methodNameCandidates);
-    }
-
-
-    // -- HELPER
-
-    private static MethodFinderOptions havingAnyOrNoAnnotation(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates,
-            final IntrospectionPolicy memberIntrospectionPolicy) {
-        return of(
-                correspondingClass,
-                methodNameCandidates,
-                memberIntrospectionPolicy.getEncapsulationPolicy(),
-                _Predicates.alwaysTrue());
-    }
-
-    private static MethodFinderOptions supportMethod(
-            final Class<?> correspondingClass,
-            final Can<String> methodNameCandidates,
-            final IntrospectionPolicy memberIntrospectionPolicy,
-            final Class<? extends Annotation> annotationType,
-            final ConflictingAnnotations conflictingAnnotations) {
-
-        return of(
-                correspondingClass,
-                methodNameCandidates,
-                // support methods are always allowed private
-                EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
-                havingAnnotationIfEnforcedByPolicyOrAccessibility(
-                        memberIntrospectionPolicy,
-                        annotationType,
-                        conflictingAnnotations.getProhibits()));
-
-    }
-
-    private static Predicate<Method> havingAnnotationIfEnforcedByPolicyOrAccessibility(
-            final IntrospectionPolicy memberIntrospectionPolicy,
-            final Class<? extends Annotation> annotationType,
-            final Can<Class<? extends Annotation>> conflictingAnnotations) {
-
-        //MemberAnnotationPolicy
-        //  when REQUIRED -> annot. on support also required
-        //  when OPTIONAL -> annot. on support only required when support method is private
-
-        return memberIntrospectionPolicy.getMemberAnnotationPolicy().isMemberAnnotationsRequired()
-                    ? method->havingAnnotation(method, annotationType, conflictingAnnotations)
-                    : method-> !_Reflect.isAccessible(method)
-                            ? havingAnnotation(method, annotationType, conflictingAnnotations)
-                            : true;
-
-    }
-
-    //FIXME[ISIS-2774] if annotation appears on an abstract method that was inherited with given method,
-    // its not detected here
-    private static boolean havingAnnotation(
-            final Method method,
-            final Class<? extends Annotation> annotationType,
-            final Can<Class<? extends Annotation>> conflictingAnnotations) {
-
-        val isMarkerAnnotationPresent = _Annotations.synthesizeInherited(method, annotationType).isPresent();
-        if(isMarkerAnnotationPresent) {
-
-            val isConflictingAnnotationPresent = conflictingAnnotations
-            .stream()
-            .anyMatch(conflictingAnnotationType->
-                    _Annotations.synthesizeInherited(method, conflictingAnnotationType).isPresent());
-
-            // do not pickup this method if conflicting - so meta-model validation will fail later on
-            return !isConflictingAnnotationPresent;
-        }
-        return isMarkerAnnotationPresent;
-    }
-
-
-
-
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java
index 766ff0f..c5df6f3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java
@@ -51,30 +51,17 @@ public final class MethodFinderPAT {
     // -- SEARCH FOR MULTIPLE NAME CANDIDATES (PAT)
 
     public Stream<MethodAndPatConstructor> findMethodWithPATArg(
-            final MethodFinderOptions options,
-            final Class<?> returnType,
+            final MethodFinder options,
             final Class<?>[] signature,
             final Can<Class<?>> additionalParamTypes) {
 
         return options.streamMethodsIgnoringSignature()
-            .filter(method -> returnType == null
-                || returnType.isAssignableFrom(method.getReturnType()))
             .filter(MethodUtil.Predicates.paramCount(1 + additionalParamTypes.size()))
             .filter(MethodUtil.Predicates.matchParamTypes(1, additionalParamTypes))
             .map(method->lookupPatConstructor(method, signature))
             .flatMap(Optional::stream);
     }
 
-    public Stream<MethodAndPatConstructor> findMethodWithPATArg_returningAnyOf(
-            final MethodFinderOptions options,
-            final Can<Class<?>> returnTypes,
-            final Class<?>[] signature,
-            final Can<Class<?>> additionalParamTypes) {
-
-        return returnTypes.stream()
-        .flatMap(returnType->findMethodWithPATArg(options, returnType, signature, additionalParamTypes));
-    }
-
     // -- HELPER
 
     private Optional<MethodAndPatConstructor> lookupPatConstructor(
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java
index 791476b..b677020 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java
@@ -18,15 +18,15 @@
  */
 package org.apache.isis.viewer.restfulobjects.viewer.mappers;
 
-import java.lang.reflect.InvocationTargetException;
+import java.util.Optional;
 
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.internal.reflection._Reflect;
 import org.apache.isis.core.metamodel.methods.MethodFinder;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
 import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
 
-import lombok.val;
 import lombok.experimental.UtilityClass;
 
 @UtilityClass
@@ -34,22 +34,18 @@ final class FailureUtil {
 
     public static HttpStatusCode getFailureStatusCodeIfAny(final Throwable ex) {
 
-        val errorCodeGetter = MethodFinderOptions.publicOnly(ex.getClass(), Can.ofSingleton("getErrorCode"))
-        .streamMethodsMatchingSignature(MethodFinderOptions.NO_ARG)
-        .filter(MethodFinder.hasReturnType(int.class))
-        .findFirst()
-        .orElse(null);
-
-        if(errorCodeGetter!=null) {
-            try {
-                val errorCode = (int)errorCodeGetter.invoke(ex);
-                return RestfulResponse.HttpStatusCode.statusFor(errorCode);
-            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                // ignore
-            }
-        }
-
-        return null;
+        return MethodFinder
+            .publicOnly(ex.getClass(), Can.ofSingleton("getErrorCode"))
+            .withRequiredReturnType(int.class)
+            .streamMethodsMatchingSignature(MethodFinder.NO_ARG)
+            .findFirst()
+            .map(errorCodeGetter->_Reflect.invokeMethodOn(errorCodeGetter, ex))
+            .map(Result::getValue)
+            .map(Optional::stream)
+            .map(Integer.class::isInstance)
+            .map(Integer.class::cast)
+            .map(RestfulResponse.HttpStatusCode::statusFor)
+            .orElse(null);
 
     }