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 2014/07/11 12:56:43 UTC

[31/61] [partial] ISIS-831: digression: moving progmodel/facets into metamodel/facets

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/multiline/annotation/MultiLineFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/multiline/annotation/MultiLineFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/multiline/annotation/MultiLineFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..0f63cec
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/multiline/annotation/MultiLineFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,62 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.multiline.annotation;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.isis.applib.annotation.MultiLine;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.propparam.multiline.MultiLineFacet;
+
+public class MultiLineFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public MultiLineFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Class<?>[] parameterTypes = processParameterContext.getMethod().getParameterTypes();
+        if (processParameterContext.getParamNum() >= parameterTypes.length) {
+            // ignore
+            return;
+        }
+        if (!Annotations.isString(parameterTypes[processParameterContext.getParamNum()])) {
+            return;
+        }
+        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof MultiLine) {
+                final MultiLine annotation = (MultiLine) parameterAnnotation;
+                FacetUtil.addFacet(create(annotation, processParameterContext.getFacetHolder()));
+                return;
+            }
+        }
+    }
+
+    private MultiLineFacet create(final MultiLine annotation, final FacetHolder holder) {
+        return (annotation != null) ? new MultiLineFacetOnParameterAnnotation(annotation.numberOfLines(), annotation.preventWrapping(), holder) : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotation.java
new file mode 100644
index 0000000..4de7e60
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotation.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.named.annotation;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacetAbstract;
+
+public class NamedFacetOnParameterAnnotation extends NamedFacetAbstract {
+
+    public NamedFacetOnParameterAnnotation(final String value, final FacetHolder holder) {
+        super(value, holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..612a63c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/annotation/NamedFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.named.annotation;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
+
+public class NamedFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public NamedFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof Named) {
+                final Named annotation = (Named) parameterAnnotation;
+                FacetUtil.addFacet(create(annotation, processParameterContext.getFacetHolder()));
+                return;
+            }
+        }
+    }
+
+    private NamedFacet create(final Named annotation, final FacetHolder holder) {
+        return annotation != null ? new NamedFacetOnParameterAnnotation(annotation.value(), holder) : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/staticmethod/NamedFacetOnParametersStaticMethodFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/staticmethod/NamedFacetOnParametersStaticMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/staticmethod/NamedFacetOnParametersStaticMethodFactory.java
new file mode 100644
index 0000000..241159c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/named/staticmethod/NamedFacetOnParametersStaticMethodFactory.java
@@ -0,0 +1,104 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.named.staticmethod;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.isis.core.commons.lang.MethodExtensions;
+import org.apache.isis.core.commons.lang.StringExtensions;
+import org.apache.isis.core.metamodel.exceptions.MetaModelException;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
+import org.apache.isis.core.metamodel.facets.members.named.staticmethod.NamedFacetStaticMethod;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
+import org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+
+/**
+ * Sets up all the {@link Facet}s for an action in a single shot.
+ */
+public class NamedFacetOnParametersStaticMethodFactory extends MethodPrefixBasedFacetFactoryAbstract {
+
+    private static final String[] PREFIXES = { MethodPrefixConstants.NAME_PREFIX };
+
+    /**
+     * Note that the {@link Facet}s registered are the generic ones from
+     * noa-architecture (where they exist)
+     */
+    public NamedFacetOnParametersStaticMethodFactory() {
+        super(FeatureType.ACTIONS_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+    }
+
+    // ///////////////////////////////////////////////////////
+    // Actions
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+
+        final FacetedMethod facetedMethod = processMethodContext.getFacetHolder();
+        final List<FacetedMethodParameter> holderList = facetedMethod.getParameters();
+
+        attachNamedFacetForParametersIfParameterNamesMethodIsFound(processMethodContext, holderList);
+    }
+
+    private static void attachNamedFacetForParametersIfParameterNamesMethodIsFound(final ProcessMethodContext processMethodContext, final List<FacetedMethodParameter> parameters) {
+
+        if (parameters.isEmpty()) {
+            return;
+        }
+
+        final Method actionMethod = processMethodContext.getMethod();
+        final String capitalizedName = StringExtensions.asCapitalizedName(actionMethod.getName());
+
+        final Class<?> cls = processMethodContext.getCls();
+        final Method namesMethod = MethodFinderUtils.findMethod(cls, MethodScope.CLASS, MethodPrefixConstants.NAME_PREFIX + capitalizedName, String[].class, new Class[0]);
+        if (namesMethod == null) {
+            return;
+        }
+        try {
+            final String[] names = invokeNamesMethod(namesMethod, parameters.size());
+            for (int i = 0; i < names.length; i++) {
+                // add facets directly to parameters, not to actions
+                FacetUtil.addFacet(new NamedFacetStaticMethod(names[i], namesMethod, parameters.get(i)));
+            }
+        } finally {
+            processMethodContext.removeMethod(namesMethod);
+        }
+    }
+
+    private static String[] invokeNamesMethod(final Method namesMethod, final int numElementsRequired) {
+        String[] names = null;
+        try {
+            names = (String[]) MethodExtensions.invokeStatic(namesMethod, new Object[0]);
+        } catch (final ClassCastException ex) {
+            // ignore
+        }
+        if (names == null || names.length != numElementsRequired) {
+            throw new MetaModelException(namesMethod + " must return an String[] array of same size as number of parameters of action");
+        }
+        return names;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotation.java
new file mode 100644
index 0000000..76f6a92
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotation.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.renderedasdaybefore.annotation;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propparam.renderedadjusted.RenderedAdjustedFacetAbstract;
+
+public class RenderedAsDayBeforeFacetOnParameterAnnotation extends RenderedAdjustedFacetAbstract {
+
+    private static final int ADJUST_BY = -1;
+
+    public RenderedAsDayBeforeFacetOnParameterAnnotation(final FacetHolder holder) {
+        super(holder, false);
+    }
+
+    @Override
+    public int value() {
+        return ADJUST_BY;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..fcd1715
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/renderedasdaybefore/annotation/RenderedAsDayBeforeFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.renderedasdaybefore.annotation;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.isis.applib.annotation.RenderedAsDayBefore;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.propparam.renderedadjusted.RenderedAdjustedFacet;
+
+public class RenderedAsDayBeforeFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public RenderedAsDayBeforeFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof RenderedAsDayBefore) {
+                final RenderedAsDayBefore annotation = (RenderedAsDayBefore) parameterAnnotation;
+                FacetUtil.addFacet(create(annotation, processParameterContext.getFacetHolder()));
+                return;
+            }
+        }
+    }
+
+    private RenderedAdjustedFacet create(final RenderedAsDayBefore annotation, final FacetHolder holder) {
+        return annotation != null ? new RenderedAsDayBeforeFacetOnParameterAnnotation(holder) : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotation.java
new file mode 100644
index 0000000..b21a4b0
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotation.java
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.typicallen.annotation;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.objpropparam.typicallen.TypicalLengthFacetAbstract;
+
+public class TypicalLengthFacetOnParameterAnnotation extends TypicalLengthFacetAbstract {
+
+    private final int value;
+
+    public TypicalLengthFacetOnParameterAnnotation(final int value, final FacetHolder holder) {
+        super(holder, false);
+        this.value = value;
+    }
+
+    @Override
+    public int value() {
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..512ba4b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/annotation/TypicalLengthFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.typicallen.annotation;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.isis.applib.annotation.TypicalLength;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.objpropparam.typicallen.TypicalLengthFacet;
+
+public class TypicalLengthFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public TypicalLengthFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof TypicalLength) {
+                final TypicalLength annotation = (TypicalLength) parameterAnnotation;
+                FacetUtil.addFacet(create(annotation, processParameterContext.getFacetHolder()));
+                return;
+            }
+        }
+    }
+
+    private TypicalLengthFacet create(final TypicalLength annotation, final FacetHolder holder) {
+        return annotation != null ? new TypicalLengthFacetOnParameterAnnotation(annotation.value(), holder) : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromType.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromType.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromType.java
new file mode 100644
index 0000000..8adf745
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromType.java
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.typicallen.fromtype;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propparam.multiline.MultiLineFacet;
+import org.apache.isis.core.metamodel.facets.objpropparam.typicallen.TypicalLengthFacet;
+import org.apache.isis.core.metamodel.facets.objpropparam.typicallen.TypicalLengthFacetAbstract;
+
+public class TypicalLengthFacetOnParameterDerivedFromType extends TypicalLengthFacetAbstract {
+
+    private final TypicalLengthFacet typicalLengthFacet;
+
+    public TypicalLengthFacetOnParameterDerivedFromType(final TypicalLengthFacet typicalLengthFacet, final FacetHolder holder) {
+        super(holder, true);
+        this.typicalLengthFacet = typicalLengthFacet;
+    }
+
+    @Override
+    public int value() {
+        final MultiLineFacet facet = getFacetHolder().getFacet(MultiLineFacet.class);
+        return facet.numberOfLines() * typicalLengthFacet.value();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory.java
new file mode 100644
index 0000000..d679b17
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/typicallen/fromtype/TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.typicallen.fromtype;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
+import org.apache.isis.core.metamodel.facets.objpropparam.typicallen.TypicalLengthFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public class TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory extends FacetFactoryAbstract {
+
+    public TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Class<?> type = processParameterContext.getMethod().getParameterTypes()[processParameterContext.getParamNum()];
+        final FacetedMethodParameter facetHolder = processParameterContext.getFacetHolder();
+        addFacetDerivedFromTypeIfPresent(facetHolder, type);
+    }
+
+    private void addFacetDerivedFromTypeIfPresent(final FacetHolder holder, final Class<?> type) {
+        final TypicalLengthFacet facet = getTypicalLengthFacet(type);
+        if (facet != null) {
+            FacetUtil.addFacet(new TypicalLengthFacetOnParameterDerivedFromType(facet, holder));
+        }
+    }
+
+    private TypicalLengthFacet getTypicalLengthFacet(final Class<?> type) {
+        final ObjectSpecification paramTypeSpec = getSpecificationLoader().loadSpecification(type);
+        return paramTypeSpec.getFacet(TypicalLengthFacet.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotation.java
new file mode 100644
index 0000000..44748a8
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotation.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.maskannot;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.mask.MaskEvaluator;
+import org.apache.isis.core.metamodel.facets.object.mask.MaskFacetAbstract;
+
+public class MaskFacetOnParameterAnnotation extends MaskFacetAbstract {
+    private final MaskEvaluator evaluator;
+
+    public MaskFacetOnParameterAnnotation(final String outputMask, final String inputMask, final FacetHolder holder) {
+        super(outputMask, holder);
+        evaluator = inputMask == null ? null : new MaskEvaluator(inputMask);
+    }
+
+    @Override
+    public boolean doesNotMatch(final ObjectAdapter adapter) {
+        if (evaluator == null) {
+            return false;
+        } else {
+            if (adapter == null) {
+                return false;
+            }
+            final Object object = adapter.getObject();
+            if (object == null) {
+                return false;
+            }
+            return !evaluator.evaluate(object.toString());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..14e62d6
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maskannot/MaskFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,77 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.maskannot;
+
+import org.apache.isis.applib.annotation.Mask;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.facets.object.mask.MaskFacet;
+import org.apache.isis.core.metamodel.facets.object.mask.TitleFacetBasedOnMask;
+
+public class MaskFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public MaskFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Class<?>[] parameterTypes = processParameterContext.getMethod().getParameterTypes();
+        if (processParameterContext.getParamNum() >= parameterTypes.length) {
+            // ignore
+            return;
+        }
+
+        final java.lang.annotation.Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (int i = 0; i < parameterAnnotations.length; i++) {
+            if (parameterAnnotations[i] instanceof Mask) {
+                final Mask annotation = (Mask) parameterAnnotations[i];
+                addMaskFacetAndCorrespondingTitleFacet(processParameterContext.getFacetHolder(), annotation, parameterTypes[i]);
+                return;
+            }
+        }
+    }
+
+    private boolean addMaskFacetAndCorrespondingTitleFacet(final FacetHolder holder, final Mask annotation, final Class<?> cls) {
+        final MaskFacet maskFacet = createMaskFacet(annotation, holder);
+        if (maskFacet == null) {
+            return false;
+        }
+        FacetUtil.addFacet(maskFacet);
+
+        final ObjectSpecification type = getSpecificationLoader().loadSpecification(cls);
+        final TitleFacet underlyingTitleFacet = type.getFacet(TitleFacet.class);
+        if (underlyingTitleFacet != null) {
+            final TitleFacet titleFacet = new TitleFacetBasedOnMask(maskFacet, underlyingTitleFacet);
+            FacetUtil.addFacet(titleFacet);
+        }
+        return true;
+    }
+
+    private MaskFacet createMaskFacet(final Mask annotation, final FacetHolder holder) {
+        return annotation != null ? new MaskFacetOnParameterAnnotation(annotation.value(), null, holder) : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotation.java
new file mode 100644
index 0000000..2bbee5b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotation.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.maxlenannot;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propparam.maxlen.MaxLengthFacetAbstract;
+
+public class MaxLengthFacetOnParameterAnnotation extends MaxLengthFacetAbstract {
+
+    public MaxLengthFacetOnParameterAnnotation(final int value, final FacetHolder holder) {
+        super(value, holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..528ddda
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/maxlenannot/MaxLengthFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.maxlenannot;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.isis.applib.annotation.MaxLength;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.propparam.maxlen.MaxLengthFacet;
+
+public class MaxLengthFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public MaxLengthFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final java.lang.annotation.Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof MaxLength) {
+                final MaxLength annotation = (MaxLength) parameterAnnotation;
+                FacetUtil.addFacet(create(annotation, processParameterContext.getFacetHolder()));
+                return;
+            }
+        }
+    }
+
+    private MaxLengthFacet create(final MaxLength annotation, final FacetHolder holder) {
+        return annotation == null ? null : new MaxLengthFacetOnParameterAnnotation(annotation.value(), holder);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacet.java
new file mode 100644
index 0000000..b246662
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacet.java
@@ -0,0 +1,66 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.mustsatisfyspec;
+
+import java.util.List;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.applib.spec.Specification;
+import org.apache.isis.applib.util.ReasonBuffer;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.interactions.ProposedHolder;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public class MustSatisfySpecificationOnParameterFacet extends FacetAbstract implements ValidatingInteractionAdvisor {
+
+    public static Class<? extends Facet> type() {
+        return MustSatisfySpecificationOnParameterFacet.class;
+    }
+
+    private final List<Specification> specifications;
+
+    public MustSatisfySpecificationOnParameterFacet(final List<Specification> specifications, final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+        this.specifications = specifications;
+    }
+
+    @Override
+    public String invalidates(final ValidityContext<? extends ValidityEvent> validityContext) {
+        if (!(validityContext instanceof ProposedHolder)) {
+            return null;
+        }
+        final ProposedHolder proposedHolder = (ProposedHolder) validityContext;
+        final ObjectAdapter targetNO = proposedHolder.getProposed();
+        if(targetNO == null) {
+            return null;
+        }
+        final Object targetObject = targetNO.getObject();
+        final ReasonBuffer buf = new ReasonBuffer();
+        for (final Specification specification : specifications) {
+            buf.append(specification.satisfies(targetObject));
+        }
+        return buf.getReason();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacetFactory.java
new file mode 100644
index 0000000..f47194f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/mustsatisfyspec/MustSatisfySpecificationOnParameterFacetFactory.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.mustsatisfyspec;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.MustSatisfy;
+import org.apache.isis.applib.spec.Specification;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+
+public class MustSatisfySpecificationOnParameterFacetFactory extends FacetFactoryAbstract {
+
+    public MustSatisfySpecificationOnParameterFacetFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final java.lang.annotation.Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof MustSatisfy) {
+                final MustSatisfy annotation = (MustSatisfy) parameterAnnotation;
+                FacetUtil.addFacet(create(annotation, processParameterContext.getFacetHolder()));
+                return;
+            }
+        }
+    }
+
+    private Facet create(final MustSatisfy annotation, final FacetHolder holder) {
+        if (annotation == null) {
+            return null;
+        }
+        final Class<?>[] values = annotation.value();
+        final List<Specification> specifications = new ArrayList<Specification>();
+        for (final Class<?> value : values) {
+            final Specification specification = newSpecificationElseNull(value);
+            if (specification != null) {
+                specifications.add(specification);
+            }
+        }
+        return specifications.size() > 0 ? new MustSatisfySpecificationOnParameterFacet(specifications, holder) : null;
+    }
+
+    private static Specification newSpecificationElseNull(final Class<?> value) {
+        if (!(Specification.class.isAssignableFrom(value))) {
+            return null;
+        }
+        try {
+            return (Specification) value.newInstance();
+        } catch (final InstantiationException e) {
+            return null;
+        } catch (final IllegalAccessException e) {
+            return null;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetFacetOnParameterAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetFacetOnParameterAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetFacetOnParameterAnnotationFactory.java
new file mode 100644
index 0000000..7463e8e
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetFacetOnParameterAnnotationFactory.java
@@ -0,0 +1,88 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.regexannot;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.isis.applib.annotation.RegEx;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.facets.object.regex.RegExFacet;
+import org.apache.isis.core.metamodel.facets.object.regex.TitleFacetFormattedByRegex;
+
+public class RegExFacetFacetOnParameterAnnotationFactory extends FacetFactoryAbstract {
+
+    public RegExFacetFacetOnParameterAnnotationFactory() {
+        super(FeatureType.PARAMETERS_ONLY);
+    }
+
+    @Override
+    public void processParams(final ProcessParameterContext processParameterContext) {
+        final Class<?>[] parameterTypes = processParameterContext.getMethod().getParameterTypes();
+        if (processParameterContext.getParamNum() >= parameterTypes.length) {
+            // ignore
+            return;
+        }
+        if (!Annotations.isString(parameterTypes[processParameterContext.getParamNum()])) {
+            return;
+        }
+
+        final Annotation[] parameterAnnotations = Annotations.getParameterAnnotations(processParameterContext.getMethod())[processParameterContext.getParamNum()];
+        for (final Annotation parameterAnnotation : parameterAnnotations) {
+            if (parameterAnnotation instanceof RegEx) {
+                final RegEx annotation = (RegEx) parameterAnnotation;
+                addRegexFacetAndCorrespondingTitleFacet(processParameterContext.getFacetHolder(), annotation);
+                return;
+            }
+        }
+    }
+
+    private void addRegexFacetAndCorrespondingTitleFacet(final FacetHolder holder, final RegEx annotation) {
+        final RegExFacet regexFacet = createRegexFacet(annotation, holder);
+        if (regexFacet == null) {
+            return;
+        }
+        FacetUtil.addFacet(regexFacet);
+
+        final TitleFacet titleFacet = createTitleFacet(regexFacet);
+        FacetUtil.addFacet(titleFacet);
+    }
+
+    private RegExFacet createRegexFacet(final RegEx annotation, final FacetHolder holder) {
+        if (annotation == null) {
+            return null;
+        }
+
+        final String validationExpression = annotation.validation();
+        final boolean caseSensitive = annotation.caseSensitive();
+        final String formatExpression = annotation.format();
+
+        return new RegExFacetOnParameterAnnotation(validationExpression, formatExpression, caseSensitive, holder);
+    }
+
+    private TitleFacet createTitleFacet(final RegExFacet regexFacet) {
+        return new TitleFacetFormattedByRegex(regexFacet);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetOnParameterAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetOnParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetOnParameterAnnotation.java
new file mode 100644
index 0000000..726620e
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validating/regexannot/RegExFacetOnParameterAnnotation.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.param.validating.regexannot;
+
+import java.util.regex.Pattern;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.regex.RegExFacetAbstract;
+
+public class RegExFacetOnParameterAnnotation extends RegExFacetAbstract {
+
+    private final Pattern pattern;
+
+    public RegExFacetOnParameterAnnotation(final String validation, final String format, final boolean caseSensitive, final FacetHolder holder) {
+        super(validation, format, caseSensitive, holder);
+        pattern = Pattern.compile(validation(), patternFlags());
+    }
+
+    @Override
+    public String format(final String text) {
+        if (text == null) {
+            return "<not a string>";
+        }
+        if (format() == null || format().length() == 0) {
+            return text;
+        }
+        return pattern.matcher(text).replaceAll(format());
+    }
+
+    @Override
+    public boolean doesNotMatch(final String text) {
+        if (text == null) {
+            return true;
+        }
+        return !pattern.matcher(text).matches();
+    }
+
+    private int patternFlags() {
+        return !caseSensitive() ? Pattern.CASE_INSENSITIVE : 0;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacet.java
new file mode 100644
index 0000000..2b6355a
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacet.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.propcoll.accessor;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+
+/**
+ * The mechanism by which the value of the property can be accessed.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to invoking the
+ * accessor method for a property OR a collection.
+ */
+public interface PropertyOrCollectionAccessorFacet extends Facet {
+
+    /**
+     * Gets the value of this property or collection from this object.
+     */
+    public Object getProperty(ObjectAdapter inObject);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacetAbstract.java
new file mode 100644
index 0000000..df4b6eb
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/accessor/PropertyOrCollectionAccessorFacetAbstract.java
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.propcoll.accessor;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+public abstract class PropertyOrCollectionAccessorFacetAbstract extends FacetAbstract implements PropertyOrCollectionAccessorFacet {
+
+    public static Class<? extends Facet> type() {
+        return PropertyOrCollectionAccessorFacet.class;
+    }
+
+    public PropertyOrCollectionAccessorFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+
+    @Override
+    public abstract Object getProperty(ObjectAdapter inObject);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacet.java
new file mode 100644
index 0000000..3256218
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacet.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.propcoll.notpersisted;
+
+import org.apache.isis.core.metamodel.facets.MarkerFacet;
+
+/**
+ * Indicates that a property or a collection shouldn't be persisted.
+ * 
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to annotating the
+ * property or collection with the <tt>@NotPersisted</tt> annotation.
+ * 
+ * <p>
+ * Note that being non-persisted does not imply being disabled; see for example:
+ * 
+ * @see http://mail-archives.apache.org/mod_mbox/incubator-isis-dev/201010.mbox/%3C4CB2FA43.7030206@nakedobjects.org%3E
+ */
+public interface NotPersistedFacet extends MarkerFacet {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacetAbstract.java
new file mode 100644
index 0000000..f56b2eb
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/propcoll/notpersisted/NotPersistedFacetAbstract.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.propcoll.notpersisted;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.MarkerFacetAbstract;
+
+public abstract class NotPersistedFacetAbstract extends MarkerFacetAbstract implements NotPersistedFacet {
+
+    public static Class<? extends Facet> type() {
+        return NotPersistedFacet.class;
+    }
+
+    public NotPersistedFacetAbstract(final FacetHolder holder) {
+        super(type(), holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java
new file mode 100644
index 0000000..6d2aa73
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.properties.accessor;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacetAbstract;
+
+public class PropertyAccessorFacetViaAccessor extends PropertyOrCollectionAccessorFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+
+    public PropertyAccessorFacetViaAccessor(final Method method, final FacetHolder holder) {
+        super(holder);
+        this.method = method;
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.ACCESSOR;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    /**
+     * Bytecode cannot automatically call
+     * {@link DomainObjectContainer#objectChanged(Object)} because cannot
+     * distinguish whether interacting with accessor to read it or to modify its
+     * contents.
+     */
+    @Override
+    public boolean impliesObjectChanged() {
+        return false;
+    }
+
+    @Override
+    public Object getProperty(final ObjectAdapter owningAdapter) {
+        return AdapterInvokeUtils.invoke(method, owningAdapter);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessorFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessorFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessorFactory.java
new file mode 100644
index 0000000..fa160d2
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessorFactory.java
@@ -0,0 +1,105 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.properties.accessor;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facetapi.MethodRemover;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+import org.apache.isis.core.metamodel.facets.PropertyOrCollectionIdentifyingFacetFactoryAbstract;
+
+public class PropertyAccessorFacetViaAccessorFactory extends PropertyOrCollectionIdentifyingFacetFactoryAbstract {
+
+    private static final String[] PREFIXES = { MethodPrefixConstants.GET_PREFIX, MethodPrefixConstants.IS_PREFIX };
+
+    public PropertyAccessorFacetViaAccessorFactory() {
+        super(FeatureType.PROPERTIES_ONLY, PREFIXES);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        attachPropertyAccessFacetForAccessorMethod(processMethodContext);
+    }
+
+    private static void attachPropertyAccessFacetForAccessorMethod(final ProcessMethodContext processMethodContext) {
+
+        final Method accessorMethod = processMethodContext.getMethod();
+
+        processMethodContext.removeMethod(accessorMethod);
+
+        final FacetHolder property = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new PropertyAccessorFacetViaAccessor(accessorMethod, property));
+    }
+
+    // ///////////////////////////////////////////////////////
+    // PropertyOrCollectionIdentifying
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public boolean isPropertyOrCollectionAccessorCandidate(final Method method) {
+        final String methodName = method.getName();
+        if (methodName.startsWith(MethodPrefixConstants.GET_PREFIX)) {
+            return true;
+        }
+        if (methodName.startsWith(MethodPrefixConstants.IS_PREFIX) && method.getReturnType() == boolean.class) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * The method way well represent a collection, but this facet factory does
+     * not have any opinion on the matter.
+     */
+    @Override
+    public boolean isCollectionAccessor(final Method method) {
+        return false;
+    }
+
+    @Override
+    public boolean isPropertyAccessor(final Method method) {
+        if (!isPropertyOrCollectionAccessorCandidate(method)) {
+            return false;
+        }
+        final Class<?> methodReturnType = method.getReturnType();
+        return isCollectionOrArray(methodReturnType);
+    }
+
+    @Override
+    public void findAndRemovePropertyAccessors(final MethodRemover methodRemover, final List<Method> methodListToAppendTo) {
+        appendMatchingMethods(methodRemover, MethodPrefixConstants.IS_PREFIX, boolean.class, methodListToAppendTo);
+        appendMatchingMethods(methodRemover, MethodPrefixConstants.GET_PREFIX, Object.class, methodListToAppendTo);
+    }
+
+    private static void appendMatchingMethods(final MethodRemover methodRemover, final String prefix, final Class<?> returnType, final List<Method> methodListToAppendTo) {
+        methodListToAppendTo.addAll(methodRemover.removeMethods(MethodScope.OBJECT, prefix, returnType, false, 0));
+    }
+
+    @Override
+    public void findAndRemoveCollectionAccessors(final MethodRemover methodRemover, final List<Method> methodListToAppendTo) {
+        // does nothing
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java
new file mode 100644
index 0000000..0c94ead
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/PropertyAutoCompleteFacetAbstract.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.properties.autocomplete;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.properties.autocomplete.PropertyAutoCompleteFacet;
+
+public abstract class PropertyAutoCompleteFacetAbstract extends FacetAbstract implements PropertyAutoCompleteFacet {
+
+    public static Class<? extends Facet> type() {
+        return PropertyAutoCompleteFacet.class;
+    }
+
+    public PropertyAutoCompleteFacetAbstract(final FacetHolder holder) {
+        super(type(), holder, Derivation.NOT_DERIVED);
+    }
+
+    @Override
+    public abstract int getMinLength();
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java
new file mode 100644
index 0000000..0131d43
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java
@@ -0,0 +1,112 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.properties.autocomplete.method;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.commons.lang.ObjectExtensions;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.properties.autocomplete.PropertyAutoCompleteFacetAbstract;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.facets.CollectionUtils;
+import org.apache.isis.core.metamodel.facets.param.autocomplete.MinLengthUtil;
+
+public class PropertyAutoCompleteFacetMethod extends PropertyAutoCompleteFacetAbstract implements ImperativeFacet {
+
+    private final Method method;
+    private final Class<?> choicesClass;
+    private final int minLength;
+
+    private final AdapterManager adapterManager;
+    private SpecificationLoader specificationLookup;
+
+    public PropertyAutoCompleteFacetMethod(final Method method, final Class<?> choicesClass, final FacetHolder holder, final SpecificationLoader specificationLookup, final AdapterManager adapterManager) {
+        super(holder);
+        this.method = method;
+        this.choicesClass = choicesClass;
+        this.specificationLookup = specificationLookup;
+        this.adapterManager = adapterManager;
+        this.minLength = MinLengthUtil.determineMinLength(method);
+    }
+
+    /**
+     * Returns a singleton list of the {@link Method} provided in the
+     * constructor.
+     */
+    @Override
+    public List<Method> getMethods() {
+        return Collections.singletonList(method);
+    }
+
+    @Override
+    public Intent getIntent(final Method method) {
+        return Intent.CHOICES_OR_AUTOCOMPLETE;
+    }
+
+    @Override
+    public int getMinLength() {
+        return minLength;
+    }
+
+    @Override
+    public boolean impliesResolve() {
+        return true;
+    }
+
+    @Override
+    public boolean impliesObjectChanged() {
+        return false;
+    }
+
+    @Override
+    public Object[] autoComplete(ObjectAdapter owningAdapter, String searchArg) {
+        final Object options = AdapterInvokeUtils.invoke(method, owningAdapter, searchArg);
+        if (options == null) {
+            return null;
+        }
+        if (options.getClass().isArray()) {
+            return ObjectExtensions.asArray(options);
+        }
+        final ObjectSpecification specification = specificationLookup.loadSpecification(choicesClass);
+        return CollectionUtils.getCollectionAsObjectArray(options, specification, getAdapterManager());
+    }
+
+    @Override
+    protected String toStringValues() {
+        return "method=" + method + ",class=" + choicesClass;
+    }
+
+    // ////////////////////////////////////////////
+    // Dependencies
+    // ////////////////////////////////////////////
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
new file mode 100644
index 0000000..8a2bee7
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
@@ -0,0 +1,81 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.facets.properties.autocomplete.method;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.commons.lang.StringExtensions;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
+import org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+
+public class PropertyAutoCompleteFacetMethodFactory extends MethodPrefixBasedFacetFactoryAbstract implements AdapterManagerAware {
+
+    private static final String[] PREFIXES = { MethodPrefixConstants.AUTO_COMPLETE_PREFIX };
+
+    private AdapterManager adapterManager;
+
+    public PropertyAutoCompleteFacetMethodFactory() {
+        super(FeatureType.PROPERTIES_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+
+        attachPropertyAutoCompleteFacetIfChoicesMethodIsFound(processMethodContext);
+    }
+
+    private void attachPropertyAutoCompleteFacetIfChoicesMethodIsFound(final ProcessMethodContext processMethodContext) {
+
+        final Method getMethod = processMethodContext.getMethod();
+        final String capitalizedName = StringExtensions.asJavaBaseName(getMethod.getName());
+
+        final Class<?> cls = processMethodContext.getCls();
+        final Class<?> returnType = getMethod.getReturnType();
+        final Method autoCompleteMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.AUTO_COMPLETE_PREFIX + capitalizedName, null, new Class[]{String.class});
+        if (autoCompleteMethod == null) {
+            return;
+        }
+        processMethodContext.removeMethod(autoCompleteMethod);
+
+        final FacetHolder property = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new PropertyAutoCompleteFacetMethod(autoCompleteMethod, returnType, property, getSpecificationLoader(), getAdapterManager()));
+    }
+
+    // ///////////////////////////////////////////////////////
+    // Dependencies (injected)
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+}