You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2017/10/30 17:27:19 UTC

[isis] branch dev/2.0.0/ISIS-1632-meta-annotations updated: ISIS-1632: converts parameter layouts facet for meta; support recursive meta annotations

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

danhaywood pushed a commit to branch dev/2.0.0/ISIS-1632-meta-annotations
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/dev/2.0.0/ISIS-1632-meta-annotations by this push:
     new 33975d2  ISIS-1632: converts parameter layouts facet for meta; support recursive meta annotations
33975d2 is described below

commit 33975d2af9a792b8afd33535603cf9a3f25445df
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Oct 30 17:26:58 2017 +0000

    ISIS-1632: converts parameter layouts facet for meta; support recursive meta annotations
---
 .../java/org/apache/isis/applib/AppManifest.java   |  11 -
 .../isis/applib/annotation/ParameterLayout.java    |   8 +-
 .../isis/applib/annotation/PropertyLayout.java     |   4 +-
 .../{RenderDayPolicy.java => RenderDay.java}       |   2 +-
 .../layout/component/PropertyLayoutData.java       |  12 +-
 ...ropertyLayoutData_renderedAsDayBefore_Test.java |  14 +-
 .../isis/core/metamodel/facets/Annotations.java    | 274 ++++++++-------------
 ...ameterFromJavaxValidationAnnotationFactory.java |  15 +-
 .../CssClassFacetForParameterLayoutAnnotation.java |  20 +-
 ...scribedAsFacetForParameterLayoutAnnotation.java |  20 +-
 .../LabelAtFacetForParameterLayoutAnnotation.java  |  18 +-
 ...MultiLineFacetForParameterLayoutAnnotation.java |  18 +-
 .../NamedFacetForParameterLayoutAnnotation.java    |  20 +-
 .../param/layout/ParameterLayoutFacetFactory.java  |  34 ++-
 ...dAdjustedFacetForParameterLayoutAnnotation.java |  27 +-
 ...calLengthFacetForParameterLayoutAnnotation.java |  18 +-
 .../parameter/ParameterAnnotationFacetFactory.java | 113 +++------
 .../FileAcceptFacetForParameterAnnotation.java     |  22 +-
 .../MandatoryFacetForParameterAnnotation.java      |  38 +--
 ...cetInvertedByNullableAnnotationOnParameter.java |   4 +-
 .../MaxLengthFacetForParameterAnnotation.java      |  18 +-
 ...fySpecificationFacetForParameterAnnotation.java |  32 +--
 .../regex/RegExFacetForParameterAnnotation.java    |  31 ++-
 .../RegExFacetForPatternAnnotationOnParameter.java |  24 +-
 .../RegExFacetForPatternAnnotationOnProperty.java  |   3 +-
 ...edAdjustedFacetForPropertyLayoutAnnotation.java |   4 +-
 .../Annotations_getAnnotations_on_Class_Test.java  | 168 +++++++++++++
 .../Annotations_getAnnotations_on_Method_Test.java | 182 ++++++++++++++
 ...notations_getAnnotations_on_Parameter_Test.java | 196 +++++++++++++++
 .../actions/ActionMethodsFacetFactoryTest.java     |  28 ---
 .../IsisComponentProvider.java                     |  17 +-
 31 files changed, 922 insertions(+), 473 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
index cc7ccd6..e6703ea 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
@@ -20,7 +20,6 @@
 package org.apache.isis.applib;
 
 import java.io.UnsupportedEncodingException;
-import java.lang.annotation.Annotation;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLDecoder;
@@ -224,16 +223,6 @@ public interface AppManifest {
         }
         //endregion
 
-        //region > metaAnnotationTypes
-        private Set<Class<? extends Annotation>> metaAnnotationTypes;
-
-        public Set<Class<? extends Annotation>> getMetaAnnotationTypes() {
-            return metaAnnotationTypes;
-        }
-        public void setMetaAnnotationTypes(final Set<Class<? extends Annotation>> metaAnnotationTypes) {
-            this.metaAnnotationTypes = metaAnnotationTypes;
-        }
-        //endregion
 
         //region > domainServiceTypes
         private Set<Class<?>> domainServiceTypes;
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/ParameterLayout.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/ParameterLayout.java
index 2fec7b2..60bf10c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/ParameterLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/ParameterLayout.java
@@ -52,7 +52,7 @@ public @interface ParameterLayout {
      * If not specified, the default depends upon the parameter value's datatype.
      * </p>
      */
-    LabelPosition labelPosition() default LabelPosition.DEFAULT;
+    LabelPosition labelPosition() default LabelPosition.NOT_SPECIFIED;
 
     /**
      * Name of this action parameter.
@@ -70,7 +70,7 @@ public @interface ParameterLayout {
     int multiLine() default -1;
 
     /**
-     * For date parameters (and properties ) only, instructs the viewer that the date should be rendered as one day
+     * For date parameters (and properties) only, instructs the viewer that the date should be rendered as one day
      * prior to the actually stored date.
      *
      * <p>
@@ -84,7 +84,7 @@ public @interface ParameterLayout {
      * <pre>
      * public void updateDates(
      *     &#64;ParameterLayout(named="From") LocalDate startDate,
-     *     &#64;ParameterLayout(named="To"), renderedAsOneDayBefore=true) LocalDate startDate) { ... }
+     *     &#64;ParameterLayout(named="To"), renderDay=RenderDay.AS_DAY_BEFORE) LocalDate endDate) { ... }
      * </pre>
      *
      * <p>
@@ -93,7 +93,7 @@ public @interface ParameterLayout {
      * In the domain object, itself, however, the value stored is 1-jun-2013.
      * </p>
      */
-    boolean renderedAsDayBefore() default false;
+    RenderDay renderDay() default RenderDay.NOT_SPECIFIED;
 
     /**
      * The typical entry length of a field, use to determine the optimum width for display
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/PropertyLayout.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/PropertyLayout.java
index 36edb5e..ec21f5f 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/PropertyLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/PropertyLayout.java
@@ -91,7 +91,7 @@ public @interface PropertyLayout {
      * <pre>
      * public LocalDate getStartDate() { ... }
      *
-     * &#64;PropertyLayout(renderedAsDayBefore=true)
+     * &#64;PropertyLayout(renderDay=RenderDay.AS_DAY_BEFORE)
      * public LocalDate getEndDate() { ... }
      * </pre>
      *
@@ -101,7 +101,7 @@ public @interface PropertyLayout {
      * In the domain object, itself, however, the value stored is 1-jun-2013.
      * </p>
      */
-    RenderDayPolicy renderDay() default RenderDayPolicy.NOT_SPECIFIED;
+    RenderDay renderDay() default RenderDay.NOT_SPECIFIED;
 
     /**
      * The typical entry length of a field, use to determine the optimum width for display
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/RenderDayPolicy.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/RenderDay.java
similarity index 97%
rename from core/applib/src/main/java/org/apache/isis/applib/annotation/RenderDayPolicy.java
rename to core/applib/src/main/java/org/apache/isis/applib/annotation/RenderDay.java
index ba5201c..37cfb21 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/RenderDayPolicy.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/RenderDay.java
@@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlType;
 @XmlType(
         namespace = "http://isis.apache.org/applib/layout/component"
 )
-public enum RenderDayPolicy {
+public enum RenderDay {
     AS_DAY,
     /**
      * Equivalent to <tt>@PropertyLayout(renderAsDayBefore=true)</tt> prior to Isis 2.x
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/component/PropertyLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/component/PropertyLayoutData.java
index 5eb4e46..ac92c05 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/component/PropertyLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/component/PropertyLayoutData.java
@@ -31,7 +31,7 @@ import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.annotation.LabelPosition;
 import org.apache.isis.applib.annotation.PromptStyle;
-import org.apache.isis.applib.annotation.RenderDayPolicy;
+import org.apache.isis.applib.annotation.RenderDay;
 import org.apache.isis.applib.annotation.Repainting;
 import org.apache.isis.applib.annotation.Where;
 
@@ -194,24 +194,24 @@ public class PropertyLayoutData
     @Deprecated
     @XmlAttribute(required = false)
     public Boolean getRenderedAsDayBefore() {
-        return getRenderDay() != null ? getRenderDay() == RenderDayPolicy.AS_DAY_BEFORE : null;
+        return getRenderDay() != null ? getRenderDay() == RenderDay.AS_DAY_BEFORE : null;
     }
 
     public void setRenderedAsDayBefore(Boolean renderedAsDayBefore) {
         if(getRenderDay() == null && renderedAsDayBefore != null) {
-            setRenderDay(renderedAsDayBefore ? RenderDayPolicy.AS_DAY_BEFORE : RenderDayPolicy.AS_DAY);
+            setRenderDay(renderedAsDayBefore ? RenderDay.AS_DAY_BEFORE : RenderDay.AS_DAY);
         }
     }
 
 
-    private RenderDayPolicy renderDay;
+    private RenderDay renderDay;
 
     @XmlAttribute(required = false)
-    public RenderDayPolicy getRenderDay() {
+    public RenderDay getRenderDay() {
         return renderDay;
     }
 
-    public void setRenderDay(final RenderDayPolicy renderDay) {
+    public void setRenderDay(final RenderDay renderDay) {
         this.renderDay = renderDay;
     }
 
diff --git a/core/applib/src/test/java/org/apache/isis/applib/layout/component/PropertyLayoutData_renderedAsDayBefore_Test.java b/core/applib/src/test/java/org/apache/isis/applib/layout/component/PropertyLayoutData_renderedAsDayBefore_Test.java
index 3c19cca..fd18c37 100644
--- a/core/applib/src/test/java/org/apache/isis/applib/layout/component/PropertyLayoutData_renderedAsDayBefore_Test.java
+++ b/core/applib/src/test/java/org/apache/isis/applib/layout/component/PropertyLayoutData_renderedAsDayBefore_Test.java
@@ -3,7 +3,7 @@ package org.apache.isis.applib.layout.component;
 import org.junit.Before;
 import org.junit.Test;
 
-import org.apache.isis.applib.annotation.RenderDayPolicy;
+import org.apache.isis.applib.annotation.RenderDay;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
@@ -27,7 +27,7 @@ public class PropertyLayoutData_renderedAsDayBefore_Test {
         data.setRenderedAsDayBefore(true);
 
         // then
-        assertThat(data.getRenderDay(), is(RenderDayPolicy.AS_DAY_BEFORE));
+        assertThat(data.getRenderDay(), is(RenderDay.AS_DAY_BEFORE));
         assertThat(data.getRenderedAsDayBefore(), is(true));
 
     }
@@ -39,7 +39,7 @@ public class PropertyLayoutData_renderedAsDayBefore_Test {
         data.setRenderedAsDayBefore(false);
 
         // then
-        assertThat(data.getRenderDay(), is(RenderDayPolicy.AS_DAY));
+        assertThat(data.getRenderDay(), is(RenderDay.AS_DAY));
         assertThat(data.getRenderedAsDayBefore(), is(false));
 
     }
@@ -48,13 +48,13 @@ public class PropertyLayoutData_renderedAsDayBefore_Test {
     public void ignore_from_setRenderedAsDayBefore_once_set_to_DAY_BEFORE() throws Exception {
 
         // given
-        data.setRenderDay(RenderDayPolicy.AS_DAY_BEFORE);
+        data.setRenderDay(RenderDay.AS_DAY_BEFORE);
 
         // when
         data.setRenderedAsDayBefore(false);
 
         // then (ignored)
-        assertThat(data.getRenderDay(), is(RenderDayPolicy.AS_DAY_BEFORE));
+        assertThat(data.getRenderDay(), is(RenderDay.AS_DAY_BEFORE));
         assertThat(data.getRenderedAsDayBefore(), is(true));
     }
 
@@ -62,13 +62,13 @@ public class PropertyLayoutData_renderedAsDayBefore_Test {
     public void ignore_from_setRenderedAsDayBefore_once_set_to_DAY() throws Exception {
 
         // given
-        data.setRenderDay(RenderDayPolicy.AS_DAY);
+        data.setRenderDay(RenderDay.AS_DAY);
 
         // when
         data.setRenderedAsDayBefore(true);
 
         // then (ignored)
-        assertThat(data.getRenderDay(), is(RenderDayPolicy.AS_DAY));
+        assertThat(data.getRenderDay(), is(RenderDay.AS_DAY));
         assertThat(data.getRenderedAsDayBefore(), is(false));
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
index 3beeb38..af966f3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
@@ -26,16 +26,13 @@ import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.validation.constraints.Pattern;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Lists;
 
-import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
@@ -114,34 +111,52 @@ public final class Annotations  {
     }
 
 
+    static class AnnotationAndDepth<T extends Annotation>
+            implements Comparable<AnnotationAndDepth<T>> {
+        AnnotationAndDepth(final T annotation, final int depth) {
+            this.annotation = annotation;
+            this.depth = depth;
+        }
+        T annotation;
+
+        private static <T extends Annotation> List<T> sorted(
+                final List<AnnotationAndDepth<T>> annotationAndDepths) {
+            Collections.sort(annotationAndDepths);
+            return annotationAndDepths.stream()
+                    .map(AnnotationAndDepth::getAnnotation)
+                    .collect(Collectors.toList());
+        }
+
+        T getAnnotation() {
+            return annotation;
+        }
+        int depth;
+
+        @Override
+        public int compareTo(final AnnotationAndDepth<T> o) {
+            return depth - o.depth;
+        }
+    }
+
+
     /**
      * Searches for annotation on provided class, and if not found for the
      * superclass.
      */
-    public static <T extends Annotation> List<T> getAnnotations(final Class<?> cls, final Class<T> annotationClass) {
-        final List<T> annotations = Lists.newArrayList();
+    public static <T extends Annotation> List<T> getAnnotations(
+            final Class<?> cls,
+            final Class<T> annotationClass) {
+
         if (cls == null) {
-            return annotations;
+            return Collections.emptyList();
         }
-        final T annotation = cls.getAnnotation(annotationClass);
-        if (annotation != null) {
-            annotations.add(annotation);
-        }
-
-        // meta annotations
-        final Set<Class<? extends Annotation>> metaAnnotationTypes = AppManifest.Registry.instance().getMetaAnnotationTypes();
-        final Annotation[] clsAnnotations = cls.getAnnotations();
-        for (final Annotation clsAnnotation : clsAnnotations) {
-            final Class<? extends Annotation> annotationType = clsAnnotation.annotationType();
-            if(metaAnnotationTypes.contains(annotationType)) {
-                final T annotationOnMetaAnnotation = annotationType.getAnnotation(annotationClass);
-                if(annotationOnMetaAnnotation != null) {
-                    annotations.add(annotationOnMetaAnnotation);
-                }
-            }
+
+        final List<AnnotationAndDepth<T>> annotationAndDepths = Lists.newArrayList();
+        for (final Annotation annotation : cls.getAnnotations()) {
+            append(annotation, annotationClass, annotationAndDepths);
         }
-        if(!annotations.isEmpty()) {
-            return annotations;
+        if(!annotationAndDepths.isEmpty()) {
+            return AnnotationAndDepth.sorted(annotationAndDepths);
         }
 
         // search superclasses
@@ -165,7 +180,35 @@ public final class Annotations  {
                 return annotationsFromInterface;
             }
         }
-        return annotations;
+        return Collections.emptyList();
+    }
+
+    private static <T extends Annotation> void append(
+            final Annotation annotation,
+            final Class<T> annotationClass,
+            final List<AnnotationAndDepth<T>> annotationAndDepths) {
+        appendWithDepth(annotation, annotationClass, annotationAndDepths, 0);
+    }
+
+    private static <T extends Annotation> void appendWithDepth(
+            final Annotation annotation,
+            final Class<T> annotationClass,
+            final List<AnnotationAndDepth<T>> annotationAndDepths,
+            final int depth) {
+        final Class<? extends Annotation> annotationType = annotation.annotationType();
+
+        // directly annotated
+        if(annotationClass.isAssignableFrom(annotationType)) {
+            annotationAndDepths.add(new AnnotationAndDepth<>((T) annotation, depth));
+        }
+
+        // if meta-annotation
+        if(annotationType.getAnnotation(Meta.class) != null) {
+            final Annotation[] annotationsOnAnnotation = annotationType.getAnnotations();
+            for (final Annotation annotationOnAnnotation : annotationsOnAnnotation) {
+                appendWithDepth(annotationOnAnnotation, annotationClass, annotationAndDepths, depth+1);
+            }
+        }
     }
 
     /**
@@ -236,88 +279,45 @@ public final class Annotations  {
     public static <T extends Annotation> List<T> getAnnotations(
             final Method method,
             final Class<T> annotationClass) {
-        final List<T> annotations = Lists.newArrayList();
         if (method == null) {
-            return annotations;
+            return Collections.emptyList();
         }
 
-        boolean annotationOnMethod = false;
-        final Class<?> methodDeclaringClass = method.getDeclaringClass();
-        final String methodName = method.getName();
-
-        final T annotation = method.getAnnotation(annotationClass);
-        if (annotation != null) {
-            annotations.add(annotation);
-            annotationOnMethod = true;
+        final List<AnnotationAndDepth<T>> annotationAndDepths = Lists.newArrayList();
+        for (final Annotation annotation : method.getAnnotations()) {
+            append(annotation, annotationClass, annotationAndDepths);
         }
-
-
-        // search for field
-        if ( !annotationOnMethod && shouldSearchForField(annotationClass) ) {
-
-            final List<String> fieldNameCandidates = fieldNameCandidatesFor(methodName);
-            for (String fieldNameCandidate : fieldNameCandidates) {
-                try {
-                    final Field field = methodDeclaringClass.getDeclaredField(fieldNameCandidate);
-                    final T fieldAnnotation = field.getAnnotation(annotationClass);
-                    if(fieldAnnotation != null) {
-                        annotations.add(fieldAnnotation);
-                    }
-                } catch (NoSuchFieldException e) {
-                    // fall through
-                }
-            }
+        if(!annotationAndDepths.isEmpty()) {
+            return AnnotationAndDepth.sorted(annotationAndDepths);
         }
 
-        // meta annotations
-        final Set<Class<? extends Annotation>> metaAnnotationTypes = AppManifest.Registry.instance().getMetaAnnotationTypes();
 
-        // search for annotation on a meta-annotation on the method
-        boolean metaAnnotationOnMethod = false;
-        final Annotation[] methodAnnotations = method.getAnnotations();
-        for (Annotation methodAnnotation : methodAnnotations) {
-            Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
-            if(metaAnnotationTypes.contains(annotationType)) {
-                final T annotationOnMetaAnnotation = annotationType.getAnnotation(annotationClass);
-                if(annotationOnMetaAnnotation != null) {
-                    annotations.add(annotationOnMetaAnnotation);
-                    metaAnnotationOnMethod = true;
-                }
-            }
-        }
 
-        // search for annotation on a meta-annotation on the field
-        if ( !metaAnnotationOnMethod && shouldSearchForField(annotationClass) ) {
+        // search for field
+        if ( !shouldSearchForField(annotationClass) ) {
 
-            List<String> fieldNameCandidates = fieldNameCandidatesFor(methodName);
+            final List<String> fieldNameCandidates = fieldNameCandidatesFor(method.getName());
             for (String fieldNameCandidate : fieldNameCandidates) {
                 try {
-                    final Field field = methodDeclaringClass.getDeclaredField(fieldNameCandidate);
-                    final Annotation[] fieldAnnotations = field.getAnnotations();
-                    for (Annotation fieldAnnotation : fieldAnnotations) {
-                        final Class<? extends Annotation> annotationType = fieldAnnotation.annotationType();
-                        if(metaAnnotationTypes.contains(annotationType)) {
-                            final T annotationOnMetaAnnotation = annotationType.getAnnotation(annotationClass);
-                            if(annotationOnMetaAnnotation != null) {
-                                annotations.add(annotationOnMetaAnnotation);
-                            }
-                        }
+                    final Field field = method.getDeclaringClass().getDeclaredField(fieldNameCandidate);
+                    for(final Annotation annotation: field.getAnnotations()) {
+                        append(annotation, annotationClass, annotationAndDepths);
                     }
                 } catch (NoSuchFieldException e) {
                     // fall through
                 }
             }
         }
-
-        if(!annotations.isEmpty()) {
-            return annotations;
+        if(!annotationAndDepths.isEmpty()) {
+            return AnnotationAndDepth.sorted(annotationAndDepths);
         }
 
+
         // search superclasses
-        final Class<?> superclass = methodDeclaringClass.getSuperclass();
+        final Class<?> superclass = method.getDeclaringClass().getSuperclass();
         if (superclass != null) {
             try {
-                final Method parentClassMethod = superclass.getMethod(methodName, method.getParameterTypes());
+                final Method parentClassMethod = superclass.getMethod(method.getName(), method.getParameterTypes());
                 final List<T> annotationsFromSuperclass = getAnnotations(parentClassMethod, annotationClass);
                 if(!annotationsFromSuperclass.isEmpty()) {
                     return annotationsFromSuperclass;
@@ -328,10 +328,10 @@ public final class Annotations  {
         }
 
         // search implemented interfaces
-        final Class<?>[] interfaces = methodDeclaringClass.getInterfaces();
+        final Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
         for (final Class<?> iface : interfaces) {
             try {
-                final Method ifaceMethod = iface.getMethod(methodName, method.getParameterTypes());
+                final Method ifaceMethod = iface.getMethod(method.getName(), method.getParameterTypes());
                 final List<T> annotationsFromInterfaces = getAnnotations(ifaceMethod, annotationClass);
                 if(!annotationsFromInterfaces.isEmpty()) {
                     return annotationsFromInterfaces;
@@ -341,7 +341,7 @@ public final class Annotations  {
             }
         }
 
-        return annotations;
+        return Collections.emptyList();
     }
 
     /**
@@ -543,95 +543,25 @@ public final class Annotations  {
      * <p>
      * Added to allow bytecode-mangling libraries such as CGLIB to be supported.
      */
-    public static Annotation[][] getParameterAnnotations(final Method method) {
-        if (method == null) {
-            return new Annotation[0][0];
-        }
-        final Annotation[][] allParamAnnotations = method.getParameterAnnotations();
-
-        boolean foundAnnotationsForAnyParameter = false;
-        for (final Annotation[] singleParamAnnotations : allParamAnnotations) {
-            if (singleParamAnnotations.length > 0) {
-                foundAnnotationsForAnyParameter = true;
-                break;
-            }
-        }
-        if (foundAnnotationsForAnyParameter) {
-            return expandMeta(allParamAnnotations);
-        }
-
-        final Class<?> methodDeclaringClass = method.getDeclaringClass();
-
-        // search superclasses
-        final Class<?> superclass = methodDeclaringClass.getSuperclass();
-        if (superclass != null) {
-            try {
-                final Method parentClassMethod = superclass.getMethod(method.getName(), method.getParameterTypes());
-                return getParameterAnnotations(parentClassMethod);
-            } catch (final SecurityException | NoSuchMethodException e) {
-                // fall through
-            }
-        }
+    public static <T extends Annotation> List<T> getAnnotations(
+            final Method method,
+            final int paramNum,
+            final Class<T> annotationClass) {
 
-        // search implemented interfaces
-        final Class<?>[] interfaces = methodDeclaringClass.getInterfaces();
-        for (final Class<?> iface : interfaces) {
-            try {
-                final Method ifaceMethod = iface.getMethod(method.getName(), method.getParameterTypes());
-                return getParameterAnnotations(ifaceMethod);
-            } catch (final SecurityException | NoSuchMethodException e) {
-                // fall through
-            }
+        if(method == null || paramNum < 0 || paramNum >= method.getParameterCount()) {
+            return Collections.emptyList();
         }
 
-        return noParamAnnotationsFor(method);
-    }
-
-    static Annotation[][] expandMeta(final Annotation[][] allParamAnnotations) {
-        Set<Class<? extends Annotation>> metaAnnotationTypes = AppManifest.Registry.instance().getMetaAnnotationTypes();
-        if(metaAnnotationTypes.isEmpty()) {
-            return allParamAnnotations;
+        final List<AnnotationAndDepth<T>> annotationAndDepths = Lists.newArrayList();
+        final Annotation[] parameterAnnotations = method.getParameterAnnotations()[paramNum];
+        for (Annotation annotation : parameterAnnotations) {
+            append(annotation, annotationClass, annotationAndDepths);
         }
-        List<Annotation[]> allParamAnnotationList = Lists.newArrayList();
-        for (Annotation[] allParamAnnotation : allParamAnnotations) {
-            List<Annotation> expandedParamAnnotations = Lists.newArrayList();
-            for (Annotation paramAnnotation : allParamAnnotation) {
-                append(paramAnnotation, expandedParamAnnotations);
-            }
-            allParamAnnotationList.add(expandedParamAnnotations.toArray(new Annotation[]{}));
-        }
-        return allParamAnnotationList.toArray(new Annotation[][]{});
-    }
-
-    static void append(final Annotation annotation, final List<Annotation> annotationsToAppendTo) {
-        Set<Class<? extends Annotation>> metaAnnotationTypes = AppManifest.Registry.instance().getMetaAnnotationTypes();
-        expandMeta(annotation, metaAnnotationTypes, annotationsToAppendTo);
-    }
-
-    static void expandMeta(
-            final Annotation annotation,
-            final Set<Class<? extends Annotation>> metaAnnotationTypes,
-            final List<Annotation> annotationsToAppendTo) {
-        final Class<? extends Annotation> annotationType = annotation.annotationType();
-        if(metaAnnotationTypes.contains(annotationType)) {
-            Annotation[] annotations = annotationType.getAnnotations();
-            annotationsToAppendTo.addAll(FluentIterable.from(Arrays.asList(annotations)).filter(
-                    new Predicate<Annotation>() {
-                        @Override
-                        public boolean apply(final Annotation annotation) {
-                            Class<? extends Annotation> annotType = annotation.annotationType();
-                            return annotType != null &&
-                                   annotType.getName().startsWith("org.apache.isis") &&
-                                   annotType != Meta.class;
-                        }
-                    }).toList());
-        } else {
-            annotationsToAppendTo.add(annotation);
+        if(!annotationAndDepths.isEmpty()) {
+            return AnnotationAndDepth.sorted(annotationAndDepths);
         }
-    }
 
-    private static Annotation[][] noParamAnnotationsFor(final Method method) {
-        return new Annotation[method.getParameterTypes().length][0];
+        return Collections.emptyList();
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/bigdecimal/javaxvaldigits/BigDecimalFacetOnParameterFromJavaxValidationAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/bigdecimal/javaxvaldigits/BigDecimalFacetOnParameterFromJavaxValidationAnnotationFactory.java
index 470846f..80b6122 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/bigdecimal/javaxvaldigits/BigDecimalFacetOnParameterFromJavaxValidationAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/bigdecimal/javaxvaldigits/BigDecimalFacetOnParameterFromJavaxValidationAnnotationFactory.java
@@ -18,9 +18,9 @@
  */
 package org.apache.isis.core.metamodel.facets.param.bigdecimal.javaxvaldigits;
 
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
+import java.util.List;
 
 import javax.validation.constraints.Digits;
 
@@ -46,22 +46,17 @@ public class BigDecimalFacetOnParameterFromJavaxValidationAnnotationFactory exte
         if(BigDecimal.class != method.getParameterTypes()[paramNum]) {
             return;
         }
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(method)[paramNum];
 
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof Digits) {
-                Digits digitsAnnotation = (Digits) parameterAnnotation;
-                FacetUtil.addFacet(create(digitsAnnotation, processParameterContext.getFacetHolder()));
-                return;
-            }
+        final List<Digits> digitsAnnots = Annotations.getAnnotations(method, paramNum, Digits.class);
+        if(digitsAnnots.size() > 0) {
+            FacetUtil.addFacet(create(digitsAnnots.get(0), processParameterContext.getFacetHolder()));
         }
     }
 
     private BigDecimalValueFacet create(final Digits annotation, final FacetHolder holder) {
         final int length = annotation.integer() + annotation.fraction();
         final int scale = annotation.fraction();
-        return annotation == null ? null : 
-            new BigDecimalFacetOnParameterFromJavaxValidationDigitsAnnotation(holder, length, scale);
+        return new BigDecimalFacetOnParameterFromJavaxValidationDigitsAnnotation(holder, length, scale);
     }
     
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/CssClassFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/CssClassFacetForParameterLayoutAnnotation.java
index abd2ef1..8969db8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/CssClassFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/CssClassFacetForParameterLayoutAnnotation.java
@@ -19,6 +19,9 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+import java.util.Objects;
+
 import com.google.common.base.Strings;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -27,12 +30,17 @@ import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacetAbstr
 
 public class CssClassFacetForParameterLayoutAnnotation extends CssClassFacetAbstract {
 
-    public static CssClassFacet create(ParameterLayout parameterLayout, FacetHolder holder) {
-        if(parameterLayout == null) {
-            return null;
-        }
-        final String cssClass = Strings.emptyToNull(parameterLayout.cssClass());
-        return cssClass != null ? new CssClassFacetForParameterLayoutAnnotation(cssClass, holder) : null;
+    public static CssClassFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .map(ParameterLayout::cssClass)
+                .map(Strings::emptyToNull)
+                .filter(Objects::nonNull)
+                .findFirst()
+                .map(cssClass -> new CssClassFacetForParameterLayoutAnnotation(cssClass, holder))
+                .orElse(null);
     }
 
     private CssClassFacetForParameterLayoutAnnotation(String value, FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/DescribedAsFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/DescribedAsFacetForParameterLayoutAnnotation.java
index 6ac10df..29f83c5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/DescribedAsFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/DescribedAsFacetForParameterLayoutAnnotation.java
@@ -19,6 +19,9 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+import java.util.Objects;
+
 import com.google.common.base.Strings;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -27,12 +30,17 @@ import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacetAbs
 
 public class DescribedAsFacetForParameterLayoutAnnotation extends DescribedAsFacetAbstract {
 
-    public static DescribedAsFacet create(ParameterLayout parameterLayout, FacetHolder holder) {
-        if(parameterLayout == null) {
-            return null;
-        }
-        final String describedAs = Strings.emptyToNull(parameterLayout.describedAs());
-        return describedAs != null ? new DescribedAsFacetForParameterLayoutAnnotation(describedAs, holder) : null;
+    public static DescribedAsFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .map(ParameterLayout::describedAs)
+                .map(Strings::emptyToNull)
+                .filter(Objects::nonNull)
+                .findFirst()
+                .map(describedAs -> new DescribedAsFacetForParameterLayoutAnnotation(describedAs, holder))
+                .orElse(null);
     }
 
     private DescribedAsFacetForParameterLayoutAnnotation(String value, FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/LabelAtFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/LabelAtFacetForParameterLayoutAnnotation.java
index 439a426..e95aac9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/LabelAtFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/LabelAtFacetForParameterLayoutAnnotation.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.LabelPosition;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -27,12 +29,16 @@ import org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacetAbs
 
 public class LabelAtFacetForParameterLayoutAnnotation extends LabelAtFacetAbstract {
 
-    public static LabelAtFacet create(final ParameterLayout parameterLayout, FacetHolder holder) {
-        if (parameterLayout == null) {
-            return null;
-        }
-        final LabelPosition labelPosition = parameterLayout.labelPosition();
-        return labelPosition != null ? new LabelAtFacetForParameterLayoutAnnotation(labelPosition, holder) : null;
+    public static LabelAtFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .map(ParameterLayout::labelPosition)
+                .filter(labelPosition -> labelPosition != LabelPosition.NOT_SPECIFIED)
+                .findFirst()
+                .map(labelPosition -> new LabelAtFacetForParameterLayoutAnnotation(labelPosition, holder))
+                .orElse(null);
     }
 
     private LabelAtFacetForParameterLayoutAnnotation(final LabelPosition value, final FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/MultiLineFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/MultiLineFacetForParameterLayoutAnnotation.java
index ff18ca3..a2aef4d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/MultiLineFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/MultiLineFacetForParameterLayoutAnnotation.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.objectvalue.multiline.MultiLineFacet;
@@ -26,12 +28,16 @@ import org.apache.isis.core.metamodel.facets.objectvalue.multiline.MultiLineFace
 
 public class MultiLineFacetForParameterLayoutAnnotation extends MultiLineFacetAbstract {
 
-    public static MultiLineFacet create(ParameterLayout parameterLayout, FacetHolder holder) {
-        if(parameterLayout == null) {
-            return null;
-        }
-        final int multiLine = parameterLayout.multiLine();
-        return multiLine != -1 ? new MultiLineFacetForParameterLayoutAnnotation(multiLine, false, holder) : null;
+    public static MultiLineFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .map(ParameterLayout::multiLine)
+                .filter(multiLine -> multiLine != -1)
+                .findFirst()
+                .map(multiLine -> new MultiLineFacetForParameterLayoutAnnotation(multiLine, false, holder))
+                .orElse(null);
     }
 
     private MultiLineFacetForParameterLayoutAnnotation(int numberOfLines, boolean preventWrapping, FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/NamedFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/NamedFacetForParameterLayoutAnnotation.java
index daacce8..33266f4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/NamedFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/NamedFacetForParameterLayoutAnnotation.java
@@ -19,20 +19,28 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+
 import com.google.common.base.Strings;
+
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.all.named.NamedFacetAbstract;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.NamedFacetForPropertyLayoutAnnotation;
 
 public class NamedFacetForParameterLayoutAnnotation extends NamedFacetAbstract {
 
-    public static NamedFacet create(ParameterLayout parameterLayout, FacetHolder holder) {
-        if(parameterLayout == null) {
-            return null;
-        }
-        final String named = Strings.emptyToNull(parameterLayout.named());
-        return named != null ? new NamedFacetForParameterLayoutAnnotation(named, parameterLayout.namedEscaped(), holder) : null;
+    public static NamedFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .filter(parameterLayout -> Strings.emptyToNull(parameterLayout.named()) != null)
+                .findFirst()
+                .map(parameterLayout -> new NamedFacetForParameterLayoutAnnotation(
+                                                parameterLayout.named(), parameterLayout.namedEscaped(), holder))
+                .orElse(null);
     }
 
     private NamedFacetForParameterLayoutAnnotation(
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/ParameterLayoutFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/ParameterLayoutFacetFactory.java
index a9f1353..f63261e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/ParameterLayoutFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/ParameterLayoutFacetFactory.java
@@ -19,10 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
-import java.lang.annotation.Annotation;
-import java.util.Set;
+import java.util.List;
 
-import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -44,26 +42,24 @@ public class ParameterLayoutFacetFactory extends FacetFactoryAbstract {
             return;
         }
 
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof ParameterLayout) {
-                final ParameterLayout parameterLayout = (ParameterLayout) parameterAnnotation;
-                addFacets(processParameterContext, parameterLayout);
-                return;
-            }
-        }
+        final List<ParameterLayout> parameterLayouts =
+                Annotations.getAnnotations(
+                        processParameterContext.getMethod(),
+                        processParameterContext.getParamNum(),
+                        ParameterLayout.class);
+        addFacets(processParameterContext, parameterLayouts);
     }
 
-    protected void addFacets(ProcessParameterContext processParameterContext, ParameterLayout parameterLayout) {
+    protected void addFacets(ProcessParameterContext processParameterContext, List<ParameterLayout> parameterLayouts) {
         final FacetedMethodParameter facetHolder = processParameterContext.getFacetHolder();
 
-        FacetUtil.addFacet(CssClassFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
-        FacetUtil.addFacet(DescribedAsFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
-        FacetUtil.addFacet(LabelAtFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
-        FacetUtil.addFacet(MultiLineFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
-        FacetUtil.addFacet(NamedFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
-        FacetUtil.addFacet(RenderedAdjustedFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
-        FacetUtil.addFacet(TypicalLengthFacetForParameterLayoutAnnotation.create(parameterLayout, facetHolder));
+        FacetUtil.addFacet(CssClassFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
+        FacetUtil.addFacet(DescribedAsFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
+        FacetUtil.addFacet(LabelAtFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
+        FacetUtil.addFacet(MultiLineFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
+        FacetUtil.addFacet(NamedFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
+        FacetUtil.addFacet(RenderedAdjustedFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
+        FacetUtil.addFacet(TypicalLengthFacetForParameterLayoutAnnotation.create(parameterLayouts, facetHolder));
 
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/RenderedAdjustedFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/RenderedAdjustedFacetForParameterLayoutAnnotation.java
index 9314a69..f3506ff 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/RenderedAdjustedFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/RenderedAdjustedFacetForParameterLayoutAnnotation.java
@@ -19,19 +19,34 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.annotation.RenderDay;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.objectvalue.renderedadjusted.RenderedAdjustedFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.renderedadjusted.RenderedAdjustedFacetAbstract;
 
 public class RenderedAdjustedFacetForParameterLayoutAnnotation extends RenderedAdjustedFacetAbstract {
 
-    public static RenderedAdjustedFacet create(ParameterLayout parameterLayout, FacetHolder holder) {
-        if(parameterLayout == null) {
-            return null;
-        }
-        final boolean renderedAsDayBefore = parameterLayout.renderedAsDayBefore();
-        return renderedAsDayBefore ? new RenderedAdjustedFacetForParameterLayoutAnnotation(holder) : null;
+    public static RenderedAdjustedFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .map(ParameterLayout::renderDay)
+                .filter(renderDay -> renderDay != RenderDay.NOT_SPECIFIED)
+                .findFirst()
+                .map(renderDay -> {
+                    switch (renderDay) {
+                    case AS_DAY:
+                        return null;
+                    case AS_DAY_BEFORE:
+                        return new RenderedAdjustedFacetForParameterLayoutAnnotation(holder);
+                    }
+                    throw new IllegalStateException("renderDay '" + renderDay + "' not recognised");
+                })
+                .orElse(null);
     }
 
     public static final int ADJUST_BY = -1;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/TypicalLengthFacetForParameterLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/TypicalLengthFacetForParameterLayoutAnnotation.java
index c194d52..0c5111c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/TypicalLengthFacetForParameterLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/layout/TypicalLengthFacetForParameterLayoutAnnotation.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.layout;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.objectvalue.typicallen.TypicalLengthFacet;
@@ -26,12 +28,16 @@ import org.apache.isis.core.metamodel.facets.objectvalue.typicallen.TypicalLengt
 
 public class TypicalLengthFacetForParameterLayoutAnnotation extends TypicalLengthFacetAbstract {
 
-    public static TypicalLengthFacet create(ParameterLayout parameterLayout, FacetHolder holder) {
-        if(parameterLayout == null) {
-            return null;
-        }
-        final int typicalLength = parameterLayout.typicalLength();
-        return typicalLength != -1 ? new TypicalLengthFacetForParameterLayoutAnnotation(typicalLength, holder) : null;
+    public static TypicalLengthFacet create(
+            final List<ParameterLayout> parameterLayouts,
+            final FacetHolder holder) {
+
+        return parameterLayouts.stream()
+                .map(ParameterLayout::typicalLength)
+                .filter(typicalLength -> typicalLength != -1)
+                .findFirst()
+                .map(typicalLength -> new TypicalLengthFacetForParameterLayoutAnnotation(typicalLength, holder))
+                .orElse(null);
     }
 
     private final int typicalLength;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
index b89d761..8626cba 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
@@ -19,8 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter;
 
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.util.List;
 
 import javax.annotation.Nullable;
 import javax.validation.constraints.Pattern;
@@ -34,7 +34,6 @@ import org.apache.isis.core.metamodel.facets.Annotations;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
 import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
-import org.apache.isis.core.metamodel.facets.objectvalue.regex.RegExFacet;
 import org.apache.isis.core.metamodel.facets.param.parameter.fileaccept.FileAcceptFacetForParameterAnnotation;
 import org.apache.isis.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetForParameterAnnotation;
 import org.apache.isis.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetInvertedByNullableAnnotationOnParameter;
@@ -76,16 +75,9 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
         final Method method = processParameterContext.getMethod();
         final int paramNum = processParameterContext.getParamNum();
         final FacetedMethodParameter holder = processParameterContext.getFacetHolder();
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(method)[paramNum];
-
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof Parameter) {
-                final Parameter parameter = (Parameter) parameterAnnotation;
-                FacetUtil.addFacet(
-                        MaxLengthFacetForParameterAnnotation.create(parameter, holder));
-                return;
-            }
-        }
+        final List<Parameter> parameters = Annotations.getAnnotations(method, paramNum, Parameter.class);
+
+        FacetUtil.addFacet(MaxLengthFacetForParameterAnnotation.create(parameters, holder));
     }
 
     void processParamsMustSatisfy(final ProcessParameterContext processParameterContext) {
@@ -93,16 +85,10 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
         final Method method = processParameterContext.getMethod();
         final int paramNum = processParameterContext.getParamNum();
         final FacetedMethodParameter holder = processParameterContext.getFacetHolder();
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(method)[paramNum];
-
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof Parameter) {
-                final Parameter parameter = (Parameter) parameterAnnotation;
-                FacetUtil.addFacet(
-                        MustSatisfySpecificationFacetForParameterAnnotation.create(parameter, holder, servicesInjector));
-                return;
-            }
-        }
+        final List<Parameter> parameters = Annotations.getAnnotations(method, paramNum, Parameter.class);
+
+        FacetUtil.addFacet(
+                MustSatisfySpecificationFacetForParameterAnnotation.create(parameters, holder, servicesInjector));
     }
 
     void processParamsRegEx(final ProcessParameterContext processParameterContext) {
@@ -111,29 +97,16 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
         final int paramNum = processParameterContext.getParamNum();
         final FacetedMethodParameter holder = processParameterContext.getFacetHolder();
         final Class<?>[] parameterTypes = method.getParameterTypes();
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(method)[paramNum];
-
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            final Class<?> parameterType = parameterTypes[paramNum];
-            if (parameterAnnotation instanceof Pattern) {
-
-                final Pattern annotation = (Pattern) parameterAnnotation;
-                final RegExFacet facet = RegExFacetForPatternAnnotationOnParameter
-                        .create(annotation, parameterType, holder);
-                FacetUtil.addFacet(facet);
-                return;
-            }
-        }
+        final Class<?> parameterType = parameterTypes[paramNum];
 
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof Parameter) {
-                final Parameter parameter = (Parameter) parameterAnnotation;
-                final Class<?> parameterType = parameterTypes[paramNum];
-                FacetUtil.addFacet(
-                        RegExFacetForParameterAnnotation.create(parameter, parameterType, holder));
-                return;
-            }
-        }
+
+        final List<Pattern> patterns = Annotations.getAnnotations(method, paramNum, Pattern.class);
+        FacetUtil.addFacet(
+                RegExFacetForPatternAnnotationOnParameter.create(patterns, parameterType, holder));
+
+        final List<Parameter> parameters = Annotations.getAnnotations(method, paramNum, Parameter.class);
+        FacetUtil.addFacet(
+                RegExFacetForParameterAnnotation.create(parameters, parameterType, holder));
     }
 
     void processParamsOptional(final ProcessParameterContext processParameterContext) {
@@ -142,31 +115,22 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
         final int paramNum = processParameterContext.getParamNum();
         final FacetedMethodParameter holder = processParameterContext.getFacetHolder();
         final Class<?>[] parameterTypes = method.getParameterTypes();
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(method)[paramNum];
-
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            final Class<?> parameterType = parameterTypes[paramNum];
-            if (parameterAnnotation instanceof javax.annotation.Nullable) {
-                final Nullable annotation = (Nullable) parameterAnnotation;
-                final MandatoryFacet facet =
-                        MandatoryFacetInvertedByNullableAnnotationOnParameter.create(annotation, parameterType, holder);
-                FacetUtil.addFacet(facet);
-                conflictingOptionalityValidator.flagIfConflict(
-                        facet, "Conflicting @Nullable with other optionality annotation");
-            }
-        }
+        final Class<?> parameterType = parameterTypes[paramNum];
+
+        final List<Nullable> nullabilities = Annotations.getAnnotations(method, paramNum, Nullable.class);
+        final MandatoryFacet facet =
+                MandatoryFacetInvertedByNullableAnnotationOnParameter.create(nullabilities, parameterType, holder);
+        FacetUtil.addFacet(facet);
+        conflictingOptionalityValidator.flagIfConflict(
+                facet, "Conflicting @Nullable with other optionality annotation");
+
+        final List<Parameter> parameters = Annotations.getAnnotations(method, paramNum, Parameter.class);
+        final MandatoryFacet mandatoryFacet =
+                MandatoryFacetForParameterAnnotation.create(parameters, parameterType, holder);
+        FacetUtil.addFacet(mandatoryFacet);
+        conflictingOptionalityValidator.flagIfConflict(
+                mandatoryFacet, "Conflicting @Parameter#optionality with other optionality annotation");
 
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof Parameter) {
-                final Parameter parameter = (Parameter) parameterAnnotation;
-                final Class<?> parameterType = parameterTypes[paramNum];
-                final MandatoryFacet facet =
-                        MandatoryFacetForParameterAnnotation.create(parameter, parameterType, holder);
-                FacetUtil.addFacet(facet);
-                conflictingOptionalityValidator.flagIfConflict(
-                        facet, "Conflicting @Parameter#optionality with other optionality annotation");
-            }
-        }
     }
 
     void processParamsFileAccept(final ProcessParameterContext processParameterContext) {
@@ -174,16 +138,9 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
         final Method method = processParameterContext.getMethod();
         final int paramNum = processParameterContext.getParamNum();
         final FacetedMethodParameter holder = processParameterContext.getFacetHolder();
-        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(method)[paramNum];
-
-        for (final Annotation parameterAnnotation : parameterAnnotations) {
-            if (parameterAnnotation instanceof Parameter) {
-                final Parameter parameter = (Parameter) parameterAnnotation;
-                FacetUtil.addFacet(
-                        FileAcceptFacetForParameterAnnotation.create(parameter, holder));
-                return;
-            }
-        }
+        final List<Parameter> parameters = Annotations.getAnnotations(method, paramNum, Parameter.class);
+
+        FacetUtil.addFacet(FileAcceptFacetForParameterAnnotation.create(parameters, holder));
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/fileaccept/FileAcceptFacetForParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/fileaccept/FileAcceptFacetForParameterAnnotation.java
index a0e1444..572a0b3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/fileaccept/FileAcceptFacetForParameterAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/fileaccept/FileAcceptFacetForParameterAnnotation.java
@@ -19,6 +19,11 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.fileaccept;
 
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.base.Strings;
+
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.objectvalue.fileaccept.FileAcceptFacet;
@@ -27,17 +32,16 @@ import org.apache.isis.core.metamodel.facets.objectvalue.fileaccept.FileAcceptFa
 public class FileAcceptFacetForParameterAnnotation extends FileAcceptFacetAbstract {
 
     public static FileAcceptFacet create(
-            final Parameter parameter,
+            final List<Parameter> parameters,
             final FacetHolder holder) {
 
-        if (parameter == null) {
-            return null;
-        }
-
-        final String fileAccept = parameter.fileAccept();
-        return !"".equals(fileAccept)
-                ? new FileAcceptFacetForParameterAnnotation(fileAccept, holder)
-                : null;
+        return parameters.stream()
+                .map(Parameter::fileAccept)
+                .map(Strings::emptyToNull)
+                .filter(Objects::nonNull)
+                .findFirst()
+                .map(fileAccept -> new FileAcceptFacetForParameterAnnotation(fileAccept, holder))
+                .orElse(null);
     }
 
     private FileAcceptFacetForParameterAnnotation(final String value, final FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetForParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetForParameterAnnotation.java
index c0ed5dd..196577d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetForParameterAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetForParameterAnnotation.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.mandatory;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -32,30 +34,32 @@ public abstract class MandatoryFacetForParameterAnnotation extends MandatoryFace
     }
 
     public static MandatoryFacet create(
-            final Parameter parameter,
+            final List<Parameter> parameters,
             final Class<?> parameterType,
             final FacetHolder holder) {
 
-        if (parameter == null) {
-            return null;
-        }
-
         if (parameterType.isPrimitive()) {
             return new MandatoryFacetForParameterAnnotation.Primitive(holder);
         }
 
-        final Optionality optionality = parameter.optionality();
-        switch (optionality) {
-            case DEFAULT:
-                // do nothing here; instead will rely on MandatoryFromJdoColumnAnnotationFacetFactory to perform
-                // the remaining processing
-                return null;
-            case MANDATORY:
-                return new MandatoryFacetForParameterAnnotation.Required(holder);
-            case OPTIONAL:
-                return new MandatoryFacetForParameterAnnotation.Optional(holder);
-        }
-        return null;
+
+        return parameters.stream()
+                .map(Parameter::optionality)
+                .filter(optionality -> optionality != Optionality.NOT_SPECIFIED)
+                .findFirst()
+                .map(optionality -> {
+                    switch (optionality) {
+                        case DEFAULT:
+                            // do nothing here
+                            return null;
+                        case MANDATORY:
+                            return new MandatoryFacetForParameterAnnotation.Required(holder);
+                        case OPTIONAL:
+                            return new MandatoryFacetForParameterAnnotation.Optional(holder);
+                    }
+                    throw new IllegalStateException("optionality '" + optionality + "' not recognised");
+                })
+                .orElse(null);
     }
 
     public static class Primitive extends MandatoryFacetForParameterAnnotation {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java
index a1dc49d..7dcaf78 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.mandatory;
 
+import java.util.List;
+
 import javax.annotation.Nullable;
 
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -35,7 +37,7 @@ import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFace
  */
 public class MandatoryFacetInvertedByNullableAnnotationOnParameter extends MandatoryFacetAbstract {
 
-    public static MandatoryFacet create(final Nullable annotation, final Class<?> parameterType, final FacetedMethodParameter holder) {
+    public static MandatoryFacet create(final List<Nullable> annotation, final Class<?> parameterType, final FacetedMethodParameter holder) {
         if(annotation == null) {
             return null;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/maxlen/MaxLengthFacetForParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/maxlen/MaxLengthFacetForParameterAnnotation.java
index 2af15ba..537534c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/maxlen/MaxLengthFacetForParameterAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/maxlen/MaxLengthFacetForParameterAnnotation.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.maxlen;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet;
@@ -27,17 +29,15 @@ import org.apache.isis.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacetAb
 public class MaxLengthFacetForParameterAnnotation extends MaxLengthFacetAbstract {
 
     public static MaxLengthFacet create(
-            final Parameter parameter,
+            final List<Parameter> parameters,
             final FacetHolder holder) {
 
-        if (parameter == null) {
-            return null;
-        }
-
-        final int maxLength = parameter.maxLength();
-        return maxLength != -1
-                ? new MaxLengthFacetForParameterAnnotation(maxLength, holder)
-                : null;
+        return parameters.stream()
+                .map(Parameter::maxLength)
+                .filter(maxLength -> maxLength != -1)
+                .findFirst()
+                .map(maxLength -> new MaxLengthFacetForParameterAnnotation(maxLength, holder))
+                .orElse(null);
     }
 
     private MaxLengthFacetForParameterAnnotation(final int value, final FacetHolder holder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
index 1a099ae..3e1e7e6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mustsatisfy/MustSatisfySpecificationFacetForParameterAnnotation.java
@@ -19,8 +19,11 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.mustsatisfy;
 
+import java.util.Arrays;
 import java.util.List;
-import com.google.common.collect.Lists;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.spec.Specification;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -31,23 +34,22 @@ import org.apache.isis.core.metamodel.services.ServicesInjector;
 public class MustSatisfySpecificationFacetForParameterAnnotation extends MustSatisfySpecificationFacetAbstract {
 
     public static Facet create(
-            final Parameter parameter,
+            final List<Parameter> parameters,
             final FacetHolder holder,
             final ServicesInjector servicesInjector) {
 
-        if (parameter == null) {
-            return null;
-        }
-
-        final Class<?>[] values = parameter.mustSatisfy();
-        final List<Specification> specifications = Lists.newArrayList();
-        for (final Class<?> value : values) {
-            final Specification specification = newSpecificationElseNull(value);
-            if (specification != null) {
-                specifications.add(specification);
-            }
-        }
-        return specifications.size() > 0 ? new MustSatisfySpecificationFacetForParameterAnnotation(specifications, holder, servicesInjector) : null;
+        List<Specification> specifications = parameters.stream()
+                .map(Parameter::mustSatisfy)
+                .flatMap(classes ->
+                        Arrays.stream(classes)
+                                .map(MustSatisfySpecificationFacetAbstract::newSpecificationElseNull)
+                                .filter(Objects::nonNull)
+                )
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+        return specifications.size() > 0
+                ? new MustSatisfySpecificationFacetForParameterAnnotation(specifications, holder, servicesInjector)
+                : null;
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForParameterAnnotation.java
index 5b47afd..6e4f437 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForParameterAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForParameterAnnotation.java
@@ -19,11 +19,13 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.regex;
 
+import java.util.List;
 import java.util.regex.Pattern;
+
 import com.google.common.base.Strings;
+
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.Annotations;
 import org.apache.isis.core.metamodel.facets.objectvalue.regex.RegExFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.regex.RegExFacetAbstract;
 
@@ -32,26 +34,21 @@ public class RegExFacetForParameterAnnotation extends RegExFacetAbstract {
     private final Pattern pattern;
 
     public static RegExFacet create(
-            final Parameter parameter,
+            final List<Parameter> parameters,
             final Class<?> parameterType,
             final FacetHolder holder) {
 
-        if (parameter == null) {
-            return null;
-        }
-        if(!Annotations.isString(parameterType)) {
-            return null;
-        }
-
-        final String pattern = parameter.regexPattern();
-        if(Strings.isNullOrEmpty(pattern)) {
-            return null;
-        }
-
-        final String replacement = parameter.regexPatternReplacement();
-        final int patternFlags = parameter.regexPatternFlags();
+        return parameters.stream()
+                .filter(parameter -> Strings.emptyToNull(parameter.regexPattern()) != null)
+                .findFirst()
+                .map(parameter -> {
+                    final String pattern = parameter.regexPattern();
+                    final String replacement = parameter.regexPatternReplacement();
+                    final int patternFlags = parameter.regexPatternFlags();
 
-        return new RegExFacetForParameterAnnotation(pattern, patternFlags, replacement, holder);
+                    return new RegExFacetForParameterAnnotation(pattern, patternFlags, replacement, holder);
+                })
+                .orElse(null);
     }
 
     private RegExFacetForParameterAnnotation(
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForPatternAnnotationOnParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForPatternAnnotationOnParameter.java
index 4b5aec0..48f4e0c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForPatternAnnotationOnParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/regex/RegExFacetForPatternAnnotationOnParameter.java
@@ -19,8 +19,11 @@
 
 package org.apache.isis.core.metamodel.facets.param.parameter.regex;
 
+import java.util.List;
 import java.util.regex.Pattern;
 
+import com.google.common.base.Strings;
+
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.Annotations;
 import org.apache.isis.core.metamodel.facets.objectvalue.regex.RegExFacet;
@@ -30,19 +33,22 @@ public class RegExFacetForPatternAnnotationOnParameter extends RegExFacetAbstrac
 
     private final Pattern pattern;
 
-    public static RegExFacet create(final javax.validation.constraints.Pattern annotation, final Class<?> parameterType, final FacetHolder holder) {
-        if (annotation == null) {
-            return null;
-        }
+    public static RegExFacet create(
+            final List<javax.validation.constraints.Pattern> patterns,
+            final Class<?> parameterType,
+            final FacetHolder holder) {
+
         if(!Annotations.isString(parameterType)) {
             return null;
         }
 
-        final String regexp = annotation.regexp();
-        final javax.validation.constraints.Pattern.Flag[] flags = annotation.flags();
-        final String message = annotation.message();
-
-        return new RegExFacetForPatternAnnotationOnParameter(regexp, flags, message, holder);
+        return patterns.stream()
+                .filter(pattern -> Strings.emptyToNull(pattern.regexp()) != null)
+                .findFirst()
+                .map(pattern ->
+                        new RegExFacetForPatternAnnotationOnParameter(
+                                pattern.regexp(), pattern.flags(), pattern.message(), holder))
+                .orElse(null);
     }
 
     private RegExFacetForPatternAnnotationOnParameter(
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/regex/RegExFacetForPatternAnnotationOnProperty.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/regex/RegExFacetForPatternAnnotationOnProperty.java
index c2363da..8b38c9d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/regex/RegExFacetForPatternAnnotationOnProperty.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/regex/RegExFacetForPatternAnnotationOnProperty.java
@@ -34,7 +34,8 @@ public class RegExFacetForPatternAnnotationOnProperty extends RegExFacetAbstract
     private final Pattern pattern;
 
     public static RegExFacet create(
-            final List<javax.validation.constraints.Pattern> patterns, final Class<?> returnType, final FacetHolder holder) {
+            final List<javax.validation.constraints.Pattern> patterns,
+            final Class<?> returnType, final FacetHolder holder) {
 
         if (!Annotations.isString(returnType)) {
             return null;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/RenderedAdjustedFacetForPropertyLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/RenderedAdjustedFacetForPropertyLayoutAnnotation.java
index c23643b..f98e43e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/RenderedAdjustedFacetForPropertyLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/RenderedAdjustedFacetForPropertyLayoutAnnotation.java
@@ -22,7 +22,7 @@ package org.apache.isis.core.metamodel.facets.properties.propertylayout;
 import java.util.List;
 
 import org.apache.isis.applib.annotation.PropertyLayout;
-import org.apache.isis.applib.annotation.RenderDayPolicy;
+import org.apache.isis.applib.annotation.RenderDay;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.objectvalue.renderedadjusted.RenderedAdjustedFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.renderedadjusted.RenderedAdjustedFacetAbstract;
@@ -35,7 +35,7 @@ public class RenderedAdjustedFacetForPropertyLayoutAnnotation extends RenderedAd
 
         return propertyLayouts.stream()
                 .map(PropertyLayout::renderDay)
-                .filter(renderDay -> renderDay != RenderDayPolicy.NOT_SPECIFIED)
+                .filter(renderDay -> renderDay != RenderDay.NOT_SPECIFIED)
                 .findFirst()
                 .map(renderDay -> {
                     switch (renderDay) {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Class_Test.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Class_Test.java
new file mode 100644
index 0000000..96401ab
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Class_Test.java
@@ -0,0 +1,168 @@
+package org.apache.isis.core.metamodel.facets;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.isis.applib.annotation.Meta;
+
+import static org.hamcrest.CoreMatchers.is;
+
+public class Annotations_getAnnotations_on_Class_Test {
+
+
+    @Inherited
+    @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface DomainObj { // cf @DomainObject
+        enum Publishng { // cf Publishing enum
+            YES,
+            NO,
+            NOT_SPECIFIED
+        }
+        Publishng publishng() default Publishng.NOT_SPECIFIED;
+    }
+
+
+    @Meta
+    @DomainObj(publishng = DomainObj.Publishng.YES)
+    @Inherited
+    @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Published {
+    }
+
+    @Meta
+    @DomainObj(publishng = DomainObj.Publishng.NO)
+    @Inherited
+    @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface NotPublished {
+    }
+
+    @Meta
+    @Published
+    @Inherited
+    @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface MetaPublished {
+    }
+
+    @Test
+    public void direct() throws Exception {
+
+        @DomainObj(publishng = DomainObj.Publishng.YES)
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta() throws Exception {
+
+        @Published
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void metaMeta() throws Exception {
+
+        @MetaPublished
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta_and_metaMeta() throws Exception {
+
+        @MetaPublished
+        @Published
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(2));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta_overrides_metaMeta() throws Exception {
+
+        @MetaPublished
+        @NotPublished
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(2));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void direct_overrides_metaMeta() throws Exception {
+
+        @MetaPublished
+        @Published
+        @DomainObj(publishng = DomainObj.Publishng.NO)
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(3));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(2).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+
+    @Test
+    public void direct_overrides_metaMeta_2() throws Exception {
+
+        @MetaPublished
+        @NotPublished
+        @DomainObj(publishng = DomainObj.Publishng.YES)
+        class SomeDomainObject {}
+
+        final List<DomainObj> annotations = Annotations
+                .getAnnotations(SomeDomainObject.class, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(3));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(2).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+}
\ No newline at end of file
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Method_Test.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Method_Test.java
new file mode 100644
index 0000000..1e6cade
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Method_Test.java
@@ -0,0 +1,182 @@
+package org.apache.isis.core.metamodel.facets;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.isis.applib.annotation.Meta;
+
+import static org.hamcrest.CoreMatchers.is;
+
+public class Annotations_getAnnotations_on_Method_Test {
+
+
+    @Inherited
+    @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface DomainObj { // cf @DomainObject
+        enum Publishng { // cf Publishing enum
+            YES,
+            NO,
+            NOT_SPECIFIED
+        }
+        Publishng publishng() default Publishng.NOT_SPECIFIED;
+    }
+
+    @Meta
+    @DomainObj(publishng = DomainObj.Publishng.YES)
+    @Inherited
+    @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Published {
+    }
+
+    @Meta
+    @DomainObj(publishng = DomainObj.Publishng.NO)
+    @Inherited
+    @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface NotPublished {
+    }
+
+    @Meta
+    @Published
+    @Inherited
+    @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface MetaPublished {
+    }
+
+    @Test
+    public void direct() throws Exception {
+
+        class SomeDomainObject {
+            @DomainObj(publishng = DomainObj.Publishng.YES)
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta() throws Exception {
+
+        class SomeDomainObject {
+            @Published
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            @MetaPublished
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta_and_metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            @MetaPublished
+            @Published
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(2));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta_overrides_metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            @MetaPublished
+            @NotPublished
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(2));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void direct_overrides_metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            @MetaPublished
+            @Published
+            @DomainObj(publishng = DomainObj.Publishng.NO)
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(3));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(2).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+
+    @Test
+    public void direct_overrides_metaMeta_2() throws Exception {
+
+        class SomeDomainObject {
+            @MetaPublished
+            @NotPublished
+            @DomainObj(publishng = DomainObj.Publishng.YES)
+            public void updateName(String name) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(3));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(2).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+}
\ No newline at end of file
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Parameter_Test.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Parameter_Test.java
new file mode 100644
index 0000000..15d0c3a
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/Annotations_getAnnotations_on_Parameter_Test.java
@@ -0,0 +1,196 @@
+package org.apache.isis.core.metamodel.facets;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.isis.applib.annotation.Meta;
+
+import static org.hamcrest.CoreMatchers.is;
+
+public class Annotations_getAnnotations_on_Parameter_Test {
+
+
+    @Inherited
+    @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface DomainObj { // cf @DomainObject
+        enum Publishng { // cf Publishing enum
+            YES,
+            NO,
+            NOT_SPECIFIED
+        }
+        Publishng publishng() default Publishng.NOT_SPECIFIED;
+    }
+
+    @Meta
+    @DomainObj(publishng = DomainObj.Publishng.YES)
+    @Inherited
+    @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Published {
+    }
+
+    @Meta
+    @DomainObj(publishng = DomainObj.Publishng.NO)
+    @Inherited
+    @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface NotPublished {
+    }
+
+    @Meta
+    @Published
+    @Inherited
+    @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface MetaPublished {
+    }
+
+    @Test
+    public void direct() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                    @DomainObj(publishng = DomainObj.Publishng.YES)
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                    @Published
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                    @MetaPublished
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(1));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta_and_metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                    @MetaPublished
+                    @Published
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(2));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void meta_overrides_metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                    @MetaPublished
+                    @NotPublished
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(2));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+    @Test
+    public void direct_overrides_metaMeta() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                    @MetaPublished
+                    @Published
+                    @DomainObj(publishng = DomainObj.Publishng.NO)
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(3));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(2).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+
+    @Test
+    public void direct_overrides_metaMeta_2() throws Exception {
+
+        class SomeDomainObject {
+            public void updateName(
+                @MetaPublished
+                @NotPublished
+                @DomainObj(publishng = DomainObj.Publishng.YES)
+                    String name
+            ) {}
+        }
+
+        Method method = SomeDomainObject.class.getMethod("updateName", String.class);
+        final List<DomainObj> annotations = Annotations.getAnnotations(method, 0, DomainObj.class);
+
+        Assert.assertThat(annotations.size(), is(3));
+
+        Assert.assertThat(annotations.get(0).publishng(), is(DomainObj.Publishng.YES));
+        Assert.assertThat(annotations.get(1).publishng(), is(DomainObj.Publishng.NO));
+        Assert.assertThat(annotations.get(2).publishng(), is(DomainObj.Publishng.YES));
+    }
+
+}
\ No newline at end of file
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/ActionMethodsFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/ActionMethodsFacetFactoryTest.java
index e8a9122..ffafafa 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/ActionMethodsFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/ActionMethodsFacetFactoryTest.java
@@ -42,7 +42,6 @@ import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFace
 import org.apache.isis.core.metamodel.facets.actions.defaults.method.ActionDefaultsFacetViaMethod;
 import org.apache.isis.core.metamodel.facets.actions.defaults.method.ActionDefaultsFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.actions.interaction.ActionNamedFacetFactory;
-import org.apache.isis.core.metamodel.facets.actions.prototype.PrototypeFacet;
 import org.apache.isis.core.metamodel.facets.actions.validate.ActionValidationFacet;
 import org.apache.isis.core.metamodel.facets.actions.validate.method.ActionValidationFacetViaMethod;
 import org.apache.isis.core.metamodel.facets.actions.validate.method.ActionValidationFacetViaMethodFactory;
@@ -163,33 +162,6 @@ public class ActionMethodsFacetFactoryTest extends AbstractFacetFactoryTest {
     }
 
 
-    public void testPicksUpExplorationPrefixAndSetsNameAppropriatelyAlso() {
-        final ActionNamedFacetFactory facetFactory = new ActionNamedFacetFactory();
-
-        facetFactory.setServicesInjector(mockServicesInjector);
-
-        // mockSpecificationLoader.setLoadSpecificationStringReturn(voidSpec);
-        allowing_specificationLoader_loadSpecification_any_willReturn(this.voidSpec);
-
-        class Customer {
-            @SuppressWarnings("unused")
-            public void explorationAnActionWithExplorationPrefix() {
-            }
-        }
-        final Method method = findMethod(Customer.class, "explorationAnActionWithExplorationPrefix");
-        facetFactory.process(new ProcessMethodContext(Customer.class, null, method, methodRemover, facetedMethod));
-
-        Facet facet = facetedMethod.getFacet(PrototypeFacet.class);
-        assertNotNull(facet);
-        assertTrue(facet instanceof PrototypeFacet);
-
-        facet = facetedMethod.getFacet(NamedFacet.class);
-        assertNotNull(facet);
-        assertTrue(facet instanceof NamedFacet);
-        final NamedFacet namedFacet = (NamedFacet) facet;
-        assertEquals("An Action With Exploration Prefix", namedFacet.value());
-    }
-
     public void testInstallsValidateMethodNoArgsFacetAndRemovesMethod() {
         final ActionValidationFacetViaMethodFactory facetFactory = new ActionValidationFacetViaMethodFactory();
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index 72eb446..3bc818f 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
@@ -19,18 +19,17 @@
 
 package org.apache.isis.core.runtime.systemusinginstallers;
 
-import java.lang.annotation.Annotation;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.annotation.Nullable;
 import javax.jdo.annotations.PersistenceCapable;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -41,7 +40,6 @@ import org.reflections.vfs.Vfs;
 import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.Meta;
 import org.apache.isis.applib.annotation.Mixin;
 import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
@@ -142,7 +140,6 @@ public abstract class IsisComponentProvider {
 
         final Reflections reflections = new Reflections(packages);
         final Set<Class<?>> domainServiceTypes = reflections.getTypesAnnotatedWith(DomainService.class);
-        final Set<Class<? extends Annotation>> annotationTypes = (Set)reflections.getTypesAnnotatedWith(Meta.class);
         final Set<Class<?>> persistenceCapableTypes = reflections.getTypesAnnotatedWith(PersistenceCapable.class);
         final Set<Class<? extends FixtureScript>> fixtureScriptTypes = reflections.getSubTypesOf(FixtureScript.class);
 
@@ -150,20 +147,14 @@ public abstract class IsisComponentProvider {
         mixinTypes.addAll(reflections.getTypesAnnotatedWith(Mixin.class));
         final Set<Class<?>> domainObjectTypes = reflections.getTypesAnnotatedWith(DomainObject.class);
         mixinTypes.addAll(
-                Lists.newArrayList(Iterables.filter(domainObjectTypes, new Predicate<Class<?>>() {
-                    @Override
-                    public boolean apply(@Nullable final Class<?> input) {
-                        if(input == null) { return false; }
-                        final DomainObject annotation = input.getAnnotation(DomainObject.class);
-                        return annotation.nature() == Nature.MIXIN;
-                    }
-                }))
+                domainObjectTypes.stream()
+                        .filter(input -> input.getAnnotation(DomainObject.class).nature() == Nature.MIXIN)
+                        .collect(Collectors.toList())
         );
 
         registry.setDomainServiceTypes(domainServiceTypes);
         registry.setPersistenceCapableTypes(persistenceCapableTypes);
         registry.setFixtureScriptTypes(fixtureScriptTypes);
-        registry.setMetaAnnotationTypes(annotationTypes);
         registry.setMixinTypes(mixinTypes);
     }
 

-- 
To stop receiving notification emails like this one, please contact
['"commits@isis.apache.org" <co...@isis.apache.org>'].