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 2012/12/05 00:41:12 UTC

[47/52] [partial] ISIS-188: consolidating isis-core

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetFactoryTest.java
new file mode 100644
index 0000000..b39e69d
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetFactoryTest.java
@@ -0,0 +1,221 @@
+/*
+ *  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.progmodel.facets.object.parseable;
+
+import org.apache.isis.applib.adapters.Parser;
+import org.apache.isis.applib.annotation.Parseable;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.runtimecontext.noruntime.RuntimeContextNoRuntime;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+
+public class ParseableFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private ParseableFacetFactory facetFactory;
+    private IsisConfigurationDefault isisConfigurationDefault;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new ParseableFacetFactory();
+        isisConfigurationDefault = new IsisConfigurationDefault();
+        facetFactory.setConfiguration(isisConfigurationDefault);
+        facetFactory.setRuntimeContext(new RuntimeContextNoRuntime(DeploymentCategory.PRODUCTION));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testFacetPickedUp() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName.class, methodRemover, facetedMethod));
+
+        final ParseableFacet facet = facetedMethod.getFacet(ParseableFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof ParseableFacetAbstract);
+    }
+
+    public void testFacetFacetHolderStored() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName.class, methodRemover, facetedMethod));
+
+        final ParseableFacetAbstract parseableFacet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertEquals(facetedMethod, parseableFacet.getFacetHolder());
+    }
+
+    public void testNoMethodsRemoved() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName.class, methodRemover, facetedMethod));
+
+        assertNoMethodsRemoved();
+    }
+
+    @Parseable(parserName = "org.apache.isis.core.progmodel.facets.object.parseable.ParseableFacetFactoryTest$MyParseableUsingParserName")
+    public static class MyParseableUsingParserName extends ParserNoop<MyParseableUsingParserName> {
+
+        /**
+         * Required since is a Parser.
+         */
+        public MyParseableUsingParserName() {
+        }
+    }
+
+    public void testParseableUsingParserName() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName.class, methodRemover, facetedMethod));
+
+        final ParseableFacetAbstract parseableFacet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertEquals(MyParseableUsingParserName.class, parseableFacet.getParserClass());
+    }
+
+    public static class ParserNoop<T> implements Parser<T> {
+        @Override
+        public T parseTextEntry(final Object context, final String entry, Localization localization) {
+            return null;
+        }
+
+        @Override
+        public int typicalLength() {
+            return 0;
+        }
+
+        @Override
+        public String displayTitleOf(final T object, final Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final T object, final String usingMask) {
+            return null;
+        }
+
+        @Override
+        public String parseableTitleOf(final T existing) {
+            return null;
+        }
+    }
+
+    @Parseable(parserClass = MyParseableUsingParserClass.class)
+    public static class MyParseableUsingParserClass extends ParserNoop<MyParseableUsingParserClass> {
+        /**
+         * Required since is a Parser.
+         */
+        public MyParseableUsingParserClass() {
+        }
+    }
+
+    public void testParseableUsingParserClass() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserClass.class, methodRemover, facetedMethod));
+
+        final ParseableFacetAbstract parseableFacet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertEquals(MyParseableUsingParserClass.class, parseableFacet.getParserClass());
+    }
+
+    public void testParseableMustBeAParser() {
+        // no test, because compiler prevents us from nominating a class that
+        // doesn't
+        // implement Parser
+    }
+
+    @Parseable(parserClass = MyParseableWithoutNoArgConstructor.class)
+    public static class MyParseableWithoutNoArgConstructor extends ParserNoop<MyParseableWithoutNoArgConstructor> {
+
+        // no no-arg constructor
+
+        public MyParseableWithoutNoArgConstructor(final int value) {
+        }
+    }
+
+    public void testParseableHaveANoArgConstructor() {
+        facetFactory.process(new ProcessClassContext(MyParseableWithoutNoArgConstructor.class, methodRemover, facetedMethod));
+
+        final ParseableFacetAbstract parseableFacet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertNull(parseableFacet);
+    }
+
+    @Parseable(parserClass = MyParseableWithoutPublicNoArgConstructor.class)
+    public static class MyParseableWithoutPublicNoArgConstructor extends ParserNoop<MyParseableWithoutPublicNoArgConstructor> {
+
+        // no public no-arg constructor
+        MyParseableWithoutPublicNoArgConstructor() {
+            this(0);
+        }
+
+        public MyParseableWithoutPublicNoArgConstructor(final int value) {
+        }
+    }
+
+    public void testParseableHaveAPublicNoArgConstructor() {
+        facetFactory.process(new ProcessClassContext(MyParseableWithoutPublicNoArgConstructor.class, methodRemover, facetedMethod));
+
+        final ParseableFacetAbstract parseableFacet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertNull(parseableFacet);
+    }
+
+    @Parseable()
+    public static class MyParseableWithParserSpecifiedUsingConfiguration extends ParserNoop<MyParseableWithParserSpecifiedUsingConfiguration> {
+
+        /**
+         * Required since is a Parser.
+         */
+        public MyParseableWithParserSpecifiedUsingConfiguration() {
+        }
+    }
+
+    public void testParserNameCanBePickedUpFromConfiguration() {
+        final String className = "org.apache.isis.core.progmodel.facets.object.parseable.ParseableFacetFactoryTest$MyParseableWithParserSpecifiedUsingConfiguration";
+        isisConfigurationDefault.add(ParserUtil.PARSER_NAME_KEY_PREFIX + canonical(className) + ParserUtil.PARSER_NAME_KEY_SUFFIX, className);
+        facetFactory.process(new ProcessClassContext(MyParseableWithParserSpecifiedUsingConfiguration.class, methodRemover, facetedMethod));
+        final ParseableFacetAbstract facet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertNotNull(facet);
+        assertEquals(MyParseableWithParserSpecifiedUsingConfiguration.class, facet.getParserClass());
+    }
+
+    public static class NonAnnotatedParseableParserSpecifiedUsingConfiguration extends ParserNoop<NonAnnotatedParseableParserSpecifiedUsingConfiguration> {
+
+        /**
+         * Required since is a Parser.
+         */
+        public NonAnnotatedParseableParserSpecifiedUsingConfiguration() {
+        }
+    }
+
+    public void testNonAnnotatedParseableCanPickUpParserFromConfiguration() {
+        final String className = "org.apache.isis.core.progmodel.facets.object.parseable.ParseableFacetFactoryTest$NonAnnotatedParseableParserSpecifiedUsingConfiguration";
+        isisConfigurationDefault.add(ParserUtil.PARSER_NAME_KEY_PREFIX + canonical(className) + ParserUtil.PARSER_NAME_KEY_SUFFIX, className);
+        facetFactory.process(new ProcessClassContext(NonAnnotatedParseableParserSpecifiedUsingConfiguration.class, methodRemover, facetedMethod));
+        final ParseableFacetAbstract facet = (ParseableFacetAbstract) facetedMethod.getFacet(ParseableFacet.class);
+        assertNotNull(facet);
+        assertEquals(NonAnnotatedParseableParserSpecifiedUsingConfiguration.class, facet.getParserClass());
+    }
+
+    private String canonical(final String className) {
+        return className.replace('$', '.');
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetUsingParserTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetUsingParserTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetUsingParserTest.java
new file mode 100644
index 0000000..5c6339a
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ParseableFacetUsingParserTest.java
@@ -0,0 +1,152 @@
+/*
+ *  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.progmodel.facets.object.parseable;
+
+import java.util.IllegalFormatWidthException;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.applib.adapters.Parser;
+import org.apache.isis.applib.adapters.ParsingException;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2.Mode;
+
+public class ParseableFacetUsingParserTest {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private FacetHolder mockFacetHolder;
+    @Mock
+    private AuthenticationSessionProvider mockAuthenticationSessionProvider;
+    @Mock
+    private ServicesInjector mockDependencyInjector;
+    @Mock
+    private AdapterManager mockAdapterManager;
+
+    private ParseableFacetUsingParser parseableFacetUsingParser;
+
+    @Before
+    public void setUp() throws Exception {
+
+        context.checking(new Expectations() {
+            {
+                never(mockAuthenticationSessionProvider);
+                never(mockAdapterManager);
+
+                allowing(mockFacetHolder).containsFacet(ValueFacet.class);
+                will(returnValue(Boolean.FALSE));
+
+                allowing(mockDependencyInjector).injectServicesInto(with(any(Object.class)));
+            }
+        });
+
+        final Parser<String> parser = new Parser<String>() {
+            @Override
+            public String parseTextEntry(final Object contextPojo, final String entry, Localization localization) {
+                if (entry.equals("invalid")) {
+                    throw new ParsingException();
+                }
+                if (entry.equals("number")) {
+                    throw new NumberFormatException();
+                }
+                if (entry.equals("format")) {
+                    throw new IllegalFormatWidthException(2);
+                }
+                return entry.toUpperCase();
+            }
+
+            @Override
+            public int typicalLength() {
+                return 0;
+            }
+
+            @Override
+            public String displayTitleOf(final String object, final Localization localization) {
+                return null;
+            }
+
+            @Override
+            public String displayTitleOf(final String object, final String usingMask) {
+                return null;
+            }
+
+            @Override
+            public String parseableTitleOf(final String existing) {
+                return null;
+            }
+        };
+        parseableFacetUsingParser = new ParseableFacetUsingParser(parser, mockFacetHolder, DeploymentCategory.PRODUCTION, mockAuthenticationSessionProvider, mockDependencyInjector, mockAdapterManager);
+    }
+
+    @Ignore
+    @Test
+    public void testParseNormalEntry() throws Exception {
+        // TODO why is this so complicated to check!!!
+        /*
+         * final AuthenticationSession session =
+         * mockery.mock(AuthenticationSession.class);
+         * 
+         * mockery.checking(new Expectations(){{
+         * one(mockAdapterManager).adapterFor("XXX");
+         * will(returnValue(mockAdapter));
+         * 
+         * one(mockAdapter).getSpecification();
+         * will(returnValue(mockSpecification));
+         * 
+         * one(mockAuthenticationSessionProvider).getAuthenticationSession();
+         * will(returnValue(session));
+         * 
+         * allowing(mockSpecification).createValidityInteractionContext(session,
+         * InteractionInvocationMethod.BY_USER, mockAdapter); }}); ObjectAdapter
+         * adapter = parseableFacetUsingParser.parseTextEntry(null, "xxx");
+         * 
+         * adapter.getObject();
+         */
+    }
+
+    @Test(expected = TextEntryParseException.class)
+    public void parsingExceptionRethrown() throws Exception {
+        parseableFacetUsingParser.parseTextEntry(null, "invalid", null);
+    }
+
+    @Test(expected = TextEntryParseException.class)
+    public void numberFormatExceptionRethrown() throws Exception {
+        parseableFacetUsingParser.parseTextEntry(null, "number", null);
+    }
+
+    @Test(expected = TextEntryParseException.class)
+    public void illegalFormatExceptionRethrown() throws Exception {
+        parseableFacetUsingParser.parseTextEntry(null, "format", null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ValueProxy.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ValueProxy.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ValueProxy.java
new file mode 100644
index 0000000..e745d61
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/parseable/ValueProxy.java
@@ -0,0 +1,23 @@
+/*
+ *  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.progmodel.facets.object.parseable;
+
+public class ValueProxy {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java
new file mode 100644
index 0000000..e4a947c
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java
@@ -0,0 +1,61 @@
+/*
+ *  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.progmodel.facets.object.stable;
+
+import org.apache.isis.applib.annotation.ViewModel;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.object.viewmodel.annotation.ViewModelAnnotationFacetFactory;
+import org.apache.isis.core.progmodel.facets.object.viewmodel.annotation.ViewModelFacetAnnotation;
+
+public class ViewModelAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private ViewModelAnnotationFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new ViewModelAnnotationFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testStableAnnotationPickedUpOnClassAndDefaultsToAlways() {
+        @ViewModel
+        class Customer {
+        }
+
+        facetFactory.process(new ProcessClassContext(Customer.class, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(ViewModelFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof ViewModelFacetAnnotation);
+
+        assertNoMethodsRemoved();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/validate/ObjectValidMethodFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/validate/ObjectValidMethodFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/validate/ObjectValidMethodFacetFactoryTest.java
new file mode 100644
index 0000000..9b21d2f
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/validate/ObjectValidMethodFacetFactoryTest.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.progmodel.facets.object.validate;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.object.validate.method.ValidateObjectFacetViaValidateMethod;
+import org.apache.isis.core.progmodel.facets.object.validate.method.ValidateObjectViaValidateMethodFacetFactory;
+
+public class ObjectValidMethodFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private ValidateObjectViaValidateMethodFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new ValidateObjectViaValidateMethodFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testValidateMethodPickedUpAndMethodRemoved() {
+        class Customer {
+            @SuppressWarnings("unused")
+            public String validate() {
+                return null;
+            }
+        }
+        final Method validateMethod = findMethod(Customer.class, "validate");
+
+        final ProcessClassContext processClassContext = new ProcessClassContext(Customer.class, methodRemover, facetHolder);
+        facetFactory.process(processClassContext);
+
+        final Facet facet = facetHolder.getFacet(ValidateObjectFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof ValidateObjectFacetViaValidateMethod);
+
+        assertTrue(methodRemover.getRemovedMethodMethodCalls().contains(validateMethod));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/value/ValueFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/value/ValueFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/value/ValueFacetFactoryTest.java
new file mode 100644
index 0000000..2c602dc
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/value/ValueFacetFactoryTest.java
@@ -0,0 +1,489 @@
+/*
+ *  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.progmodel.facets.object.value;
+
+import org.apache.isis.applib.adapters.AbstractValueSemanticsProvider;
+import org.apache.isis.applib.adapters.DefaultsProvider;
+import org.apache.isis.applib.adapters.EncoderDecoder;
+import org.apache.isis.applib.adapters.Parser;
+import org.apache.isis.applib.annotation.Value;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.metamodel.facets.ebc.EqualByContentFacet;
+import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
+import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.facets.typicallen.TypicalLengthFacet;
+import org.apache.isis.core.metamodel.runtimecontext.noruntime.RuntimeContextNoRuntime;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.object.defaults.DefaultedFacet;
+import org.apache.isis.core.progmodel.facets.object.value.annotation.ValueFacetAnnotation;
+import org.apache.isis.core.progmodel.facets.object.value.annotation.ValueFacetFactory;
+
+public class ValueFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private ValueFacetFactory facetFactory;
+    private IsisConfigurationDefault isisConfigurationDefault;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new ValueFacetFactory();
+        isisConfigurationDefault = new IsisConfigurationDefault();
+        facetFactory.setConfiguration(isisConfigurationDefault);
+        facetFactory.setRuntimeContext(new RuntimeContextNoRuntime(DeploymentCategory.PRODUCTION));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyParseableUsingParserName2")
+    public static class MyParseableUsingParserName2 extends AbstractValueSemanticsProvider<MyValueSemanticsProviderUsingSemanticsProviderName> {
+
+        /**
+         * Required since is a Parser.
+         */
+        public MyParseableUsingParserName2() {
+        }
+
+    }
+
+    public void testFacetPickedUp() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName2.class, methodRemover, facetedMethod));
+
+        final ValueFacet facet = facetedMethod.getFacet(ValueFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof ValueFacetAnnotation);
+    }
+
+    public void testFacetFacetHolderStored() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName2.class, methodRemover, facetedMethod));
+
+        final ValueFacetAnnotation valueFacet = (ValueFacetAnnotation) facetedMethod.getFacet(ValueFacet.class);
+        assertEquals(facetedMethod, valueFacet.getFacetHolder());
+    }
+
+    public void testNoMethodsRemoved() {
+
+        facetFactory.process(new ProcessClassContext(MyParseableUsingParserName2.class, methodRemover, facetedMethod));
+
+        assertNoMethodsRemoved();
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderUsingSemanticsProviderName")
+    public static class MyValueSemanticsProviderUsingSemanticsProviderName extends AbstractValueSemanticsProvider<MyValueSemanticsProviderUsingSemanticsProviderName> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderUsingSemanticsProviderName() {
+        }
+    }
+
+    public void testPickUpSemanticsProviderViaNameAndInstallsValueFacet() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderUsingSemanticsProviderName.class, methodRemover, facetedMethod));
+
+        assertNotNull(facetedMethod.getFacet(ValueFacet.class));
+    }
+
+    @Value(semanticsProviderClass = MyValueSemanticsProviderUsingSemanticsProviderClass.class)
+    public static class MyValueSemanticsProviderUsingSemanticsProviderClass extends AbstractValueSemanticsProvider<MyValueSemanticsProviderUsingSemanticsProviderClass> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderUsingSemanticsProviderClass() {
+        }
+    }
+
+    public void testPickUpSemanticsProviderViaClassAndInstallsValueFacet() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderUsingSemanticsProviderClass.class, methodRemover, facetedMethod));
+
+        assertNotNull(facetedMethod.getFacet(ValueFacet.class));
+    }
+
+    public void testValueSemanticsProviderMustBeAValueSemanticsProvider() {
+        // no test, because compiler prevents us from nominating a class that
+        // doesn't
+        // implement ValueSemanticsProvider
+    }
+
+    @Value(semanticsProviderClass = MyValueSemanticsProviderWithoutNoArgConstructor.class)
+    public static class MyValueSemanticsProviderWithoutNoArgConstructor extends AbstractValueSemanticsProvider<MyValueSemanticsProviderWithoutNoArgConstructor> {
+
+        // no no-arg constructor
+
+        // pass in false for an immutable, which isn't the default
+        public MyValueSemanticsProviderWithoutNoArgConstructor(final int value) {
+            super(false, false);
+        }
+    }
+
+    public void testValueSemanticsProviderMustHaveANoArgConstructor() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderWithoutNoArgConstructor.class, methodRemover, facetedMethod));
+
+        // the fact that we have an immutable means that the provider wasn't
+        // picked up
+        assertNotNull(facetedMethod.getFacet(ImmutableFacet.class));
+    }
+
+    @Value(semanticsProviderClass = MyValueSemanticsProviderWithoutPublicNoArgConstructor.class)
+    public static class MyValueSemanticsProviderWithoutPublicNoArgConstructor extends AbstractValueSemanticsProvider<MyValueSemanticsProviderWithoutPublicNoArgConstructor> {
+
+        // no public no-arg constructor
+
+        // pass in false for an immutable, which isn't the default
+        MyValueSemanticsProviderWithoutPublicNoArgConstructor() {
+            super(false, false);
+        }
+
+        public MyValueSemanticsProviderWithoutPublicNoArgConstructor(final int value) {
+        }
+    }
+
+    public void testValueSemanticsProviderMustHaveAPublicNoArgConstructor() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderWithoutPublicNoArgConstructor.class, methodRemover, facetedMethod));
+
+        // the fact that we have an immutable means that the provider wasn't
+        // picked up
+        assertNotNull(facetedMethod.getFacet(ImmutableFacet.class));
+    }
+
+    public void testValueSemanticsProviderThatIsNotAParserDoesNotInstallParseableFacet() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderUsingSemanticsProviderClass.class, methodRemover, facetedMethod));
+        assertNull(facetedMethod.getFacet(ParseableFacet.class));
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatIsAParser")
+    public static class MyValueSemanticsProviderThatIsAParser extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatIsAParser> implements Parser<MyValueSemanticsProviderThatIsAParser> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatIsAParser() {
+        }
+
+        @Override
+        public MyValueSemanticsProviderThatIsAParser parseTextEntry(final Object context, final String entry, Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final MyValueSemanticsProviderThatIsAParser object, final Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final MyValueSemanticsProviderThatIsAParser object, final String usingMask) {
+            return null;
+        }
+
+        @Override
+        public String parseableTitleOf(final MyValueSemanticsProviderThatIsAParser existing) {
+            return null;
+        }
+
+        @Override
+        public int typicalLength() {
+            return 0;
+        }
+    }
+
+    public void testValueSemanticsProviderThatIsAParserInstallsParseableFacet() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatIsAParser.class, methodRemover, facetedMethod));
+        assertNotNull(facetedMethod.getFacet(ParseableFacet.class));
+    }
+
+    public void testValueSemanticsProviderThatIsAParserInstallsTitleFacet() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatIsAParser.class, methodRemover, facetedMethod));
+        assertNotNull(facetedMethod.getFacet(TitleFacet.class));
+    }
+
+    public void testValueSemanticsProviderThatIsAParserInstallsTypicalLengthFacet() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatIsAParser.class, methodRemover, facetedMethod));
+        assertNotNull(facetedMethod.getFacet(TypicalLengthFacet.class));
+    }
+
+    public void testValueSemanticsProviderThatIsNotADefaultsProviderDoesNotInstallDefaultedFacet() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderUsingSemanticsProviderClass.class, methodRemover, facetedMethod));
+        assertNull(facetedMethod.getFacet(DefaultedFacet.class));
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatIsADefaultsProvider")
+    public static class MyValueSemanticsProviderThatIsADefaultsProvider extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatIsADefaultsProvider> implements DefaultsProvider<MyValueSemanticsProviderThatIsADefaultsProvider> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatIsADefaultsProvider() {
+        }
+
+        @Override
+        public MyValueSemanticsProviderThatIsADefaultsProvider getDefaultValue() {
+            return new MyValueSemanticsProviderThatIsADefaultsProvider();
+        }
+    }
+
+    public void testValueSemanticsProviderThatIsADefaultsProviderInstallsDefaultedFacet() {
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatIsADefaultsProvider.class, methodRemover, facetedMethod));
+        assertNotNull(facetedMethod.getFacet(DefaultedFacet.class));
+    }
+
+    public void testValueSemanticsProviderThatIsNotAnEncoderDecoderDoesNotInstallEncodeableFacet() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderUsingSemanticsProviderClass.class, methodRemover, facetedMethod));
+
+        assertNull(facetedMethod.getFacet(EncodableFacet.class));
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatIsAnEncoderDecoder")
+    public static class MyValueSemanticsProviderThatIsAnEncoderDecoder extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatIsAnEncoderDecoder> implements EncoderDecoder<MyValueSemanticsProviderThatIsAnEncoderDecoder> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatIsAnEncoderDecoder() {
+        }
+
+        @Override
+        public MyValueSemanticsProviderThatIsAnEncoderDecoder fromEncodedString(final String encodedString) {
+            return null;
+        }
+
+        @Override
+        public String toEncodedString(final MyValueSemanticsProviderThatIsAnEncoderDecoder toEncode) {
+            return null;
+        }
+    }
+
+    public void testValueSemanticsProviderThatIsAnEncoderInstallsEncodeableFacet() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatIsAnEncoderDecoder.class, methodRemover, facetedMethod));
+
+        assertNotNull(facetedMethod.getFacet(EncodableFacet.class));
+    }
+
+    public void testImmutableFacetsIsInstalledIfNoSemanticsProviderSpecified() {
+
+        @Value()
+        class MyNumberImmutableDefault {
+        }
+
+        facetFactory.process(new ProcessClassContext(MyNumberImmutableDefault.class, methodRemover, facetedMethod));
+
+        final ImmutableFacet facet = facetedMethod.getFacet(ImmutableFacet.class);
+        assertNotNull(facet);
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatSpecifiesImmutableSemantic")
+    public static class MyValueSemanticsProviderThatSpecifiesImmutableSemantic extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatSpecifiesImmutableSemantic> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatSpecifiesImmutableSemantic() {
+            super(true, true);
+        }
+    }
+
+    public void testImmutableFacetsIsInstalledIfSpecifiesImmutable() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatSpecifiesImmutableSemantic.class, methodRemover, facetedMethod));
+
+        final ImmutableFacet facet = facetedMethod.getFacet(ImmutableFacet.class);
+        assertNotNull(facet);
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatSpecifiesNotImmutableSemantic")
+    public static class MyValueSemanticsProviderThatSpecifiesNotImmutableSemantic extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatSpecifiesNotImmutableSemantic> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatSpecifiesNotImmutableSemantic() {
+            super(false, true);
+        }
+    }
+
+    public void testImmutableFacetsIsNotInstalledIfSpecifiesNotImmutable() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatSpecifiesNotImmutableSemantic.class, methodRemover, facetedMethod));
+
+        final ImmutableFacet facet = facetedMethod.getFacet(ImmutableFacet.class);
+        assertNull(facet);
+    }
+
+    public void testEqualByContentFacetsIsInstalledIfNoSemanticsProviderSpecified() {
+
+        @Value()
+        class MyNumberEqualByContentDefault {
+        }
+
+        facetFactory.process(new ProcessClassContext(MyNumberEqualByContentDefault.class, methodRemover, facetedMethod));
+
+        final EqualByContentFacet facet = facetedMethod.getFacet(EqualByContentFacet.class);
+        assertNotNull(facet);
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatSpecifiesEqualByContentSemantic")
+    public static class MyValueSemanticsProviderThatSpecifiesEqualByContentSemantic extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatSpecifiesEqualByContentSemantic> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatSpecifiesEqualByContentSemantic() {
+            super(true, true);
+        }
+    }
+
+    public void testEqualByContentFacetsIsInstalledIfSpecifiesEqualByContent() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatSpecifiesEqualByContentSemantic.class, methodRemover, facetedMethod));
+
+        final EqualByContentFacet facet = facetedMethod.getFacet(EqualByContentFacet.class);
+        assertNotNull(facet);
+    }
+
+    @Value(semanticsProviderName = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueSemanticsProviderThatSpecifiesNotEqualByContentSemantic")
+    public static class MyValueSemanticsProviderThatSpecifiesNotEqualByContentSemantic extends AbstractValueSemanticsProvider<MyValueSemanticsProviderThatSpecifiesNotEqualByContentSemantic> {
+
+        /**
+         * Required since is a ValueSemanticsProvider.
+         */
+        public MyValueSemanticsProviderThatSpecifiesNotEqualByContentSemantic() {
+            super(false, false);
+        }
+    }
+
+    public void testEqualByContentFacetsIsNotInstalledIfSpecifiesNotEqualByContent() {
+
+        facetFactory.process(new ProcessClassContext(MyValueSemanticsProviderThatSpecifiesNotEqualByContentSemantic.class, methodRemover, facetedMethod));
+
+        final EqualByContentFacet facet = facetedMethod.getFacet(EqualByContentFacet.class);
+        assertNull(facet);
+    }
+
+    @Value()
+    public static class MyValueWithSemanticsProviderSpecifiedUsingConfiguration extends AbstractValueSemanticsProvider<MyValueWithSemanticsProviderSpecifiedUsingConfiguration> implements Parser<MyValueWithSemanticsProviderSpecifiedUsingConfiguration> {
+
+        /**
+         * Required since is a SemanticsProvider.
+         */
+        public MyValueWithSemanticsProviderSpecifiedUsingConfiguration() {
+        }
+
+        @Override
+        public MyValueWithSemanticsProviderSpecifiedUsingConfiguration parseTextEntry(final Object context, final String entry, Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final MyValueWithSemanticsProviderSpecifiedUsingConfiguration object, final Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final MyValueWithSemanticsProviderSpecifiedUsingConfiguration object, final String usingMask) {
+            return null;
+        }
+
+        @Override
+        public String parseableTitleOf(final MyValueWithSemanticsProviderSpecifiedUsingConfiguration existing) {
+            return null;
+        }
+
+        @Override
+        public int typicalLength() {
+            return 0;
+        }
+    }
+
+    public void testSemanticsProviderNameCanBePickedUpFromConfiguration() {
+        final String className = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$MyValueWithSemanticsProviderSpecifiedUsingConfiguration";
+        isisConfigurationDefault.add(ValueSemanticsProviderUtil.SEMANTICS_PROVIDER_NAME_KEY_PREFIX + canonical(className) + ValueSemanticsProviderUtil.SEMANTICS_PROVIDER_NAME_KEY_SUFFIX, className);
+        facetFactory.process(new ProcessClassContext(MyValueWithSemanticsProviderSpecifiedUsingConfiguration.class, methodRemover, facetedMethod));
+        final ValueFacetAbstract facet = (ValueFacetAbstract) facetedMethod.getFacet(ValueFacet.class);
+        assertNotNull(facet);
+        // should also be a ParserFacet, since the VSP implements Parser
+        final ParseableFacet parseableFacet = facetedMethod.getFacet(ParseableFacet.class);
+        assertNotNull(parseableFacet);
+    }
+
+    public static class NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration extends AbstractValueSemanticsProvider<NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration> implements Parser<NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration> {
+        /**
+         * Required since is a SemanticsProvider.
+         */
+        public NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration() {
+        }
+
+        @Override
+        public NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration parseTextEntry(final Object context, final String entry, Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration object, final Localization localization) {
+            return null;
+        }
+
+        @Override
+        public String displayTitleOf(final NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration object, final String usingMask) {
+            return null;
+        }
+
+        @Override
+        public String parseableTitleOf(final NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration existing) {
+            return null;
+        }
+
+        @Override
+        public int typicalLength() {
+            return 0;
+        }
+    }
+
+    public void testNonAnnotatedValueCanPickUpSemanticsProviderFromConfiguration() {
+        final String className = "org.apache.isis.core.progmodel.facets.object.value.ValueFacetFactoryTest$NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration";
+        isisConfigurationDefault.add(ValueSemanticsProviderUtil.SEMANTICS_PROVIDER_NAME_KEY_PREFIX + canonical(className) + ValueSemanticsProviderUtil.SEMANTICS_PROVIDER_NAME_KEY_SUFFIX, className);
+        facetFactory.process(new ProcessClassContext(NonAnnotatedValueSemanticsProviderSpecifiedUsingConfiguration.class, methodRemover, facetedMethod));
+        final ValueFacetAbstract facet = (ValueFacetAbstract) facetedMethod.getFacet(ValueFacet.class);
+        assertNotNull(facet);
+        // should also be a ParserFacet, since the VSP implements Parser
+        final ParseableFacet parseableFacet = facetedMethod.getFacet(ParseableFacet.class);
+        assertNotNull(parseableFacet);
+    }
+
+    private String canonical(final String className) {
+        return className.replace('$', '.');
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/actionorder/ActionOrderAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/actionorder/ActionOrderAnnotationFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/actionorder/ActionOrderAnnotationFacetFactoryTest.java
new file mode 100644
index 0000000..a68b991
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/actionorder/ActionOrderAnnotationFacetFactoryTest.java
@@ -0,0 +1,63 @@
+/*
+ *  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.progmodel.facets.ordering.actionorder;
+
+import org.apache.isis.applib.annotation.ActionOrder;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.metamodel.facets.object.orderactions.ActionOrderFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.object.orderactions.ActionOrderAnnotationFacetFactory;
+import org.apache.isis.core.progmodel.facets.object.orderactions.ActionOrderFacetAnnotation;
+
+public class ActionOrderAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private ActionOrderAnnotationFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new ActionOrderAnnotationFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testActionOrderAnnotationPickedUpOnClass() {
+        @ActionOrder("foo,bar")
+        class Customer {
+        }
+
+        facetFactory.process(new ProcessClassContext(Customer.class, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(ActionOrderFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof ActionOrderFacetAnnotation);
+        final ActionOrderFacetAnnotation actionOrderFacetAnnotation = (ActionOrderFacetAnnotation) facet;
+        assertEquals("foo,bar", actionOrderFacetAnnotation.value());
+
+        assertNoMethodsRemoved();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/fieldorder/FieldOrderAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/fieldorder/FieldOrderAnnotationFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/fieldorder/FieldOrderAnnotationFacetFactoryTest.java
new file mode 100644
index 0000000..4030b7b
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/fieldorder/FieldOrderAnnotationFacetFactoryTest.java
@@ -0,0 +1,63 @@
+/*
+ *  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.progmodel.facets.ordering.fieldorder;
+
+import org.apache.isis.applib.annotation.FieldOrder;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.metamodel.facets.object.orderfields.FieldOrderFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.object.orderfields.FieldOrderAnnotationFacetFactory;
+import org.apache.isis.core.progmodel.facets.object.orderfields.FieldOrderFacetAnnotation;
+
+public class FieldOrderAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private FieldOrderAnnotationFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new FieldOrderAnnotationFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testFieldOrderAnnotationPickedUpOnClass() {
+        @FieldOrder("foo,bar")
+        class Customer {
+        }
+
+        facetFactory.process(new ProcessClassContext(Customer.class, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(FieldOrderFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof FieldOrderFacetAnnotation);
+        final FieldOrderFacetAnnotation fieldOrderFacetAnnotation = (FieldOrderFacetAnnotation) facet;
+        assertEquals("foo,bar", fieldOrderFacetAnnotation.value());
+
+        assertNoMethodsRemoved();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/DeweyOrderSetTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/DeweyOrderSetTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/DeweyOrderSetTest.java
new file mode 100644
index 0000000..9581190
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/DeweyOrderSetTest.java
@@ -0,0 +1,238 @@
+/*
+ *  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.progmodel.facets.ordering.memberorder;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.google.common.collect.ImmutableList;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.layout.OrderSet;
+import org.apache.isis.core.metamodel.layout.memberorderfacet.DeweyOrderSet;
+import org.apache.isis.core.progmodel.facets.members.order.MemberOrderFacetAnnotation;
+
+public class DeweyOrderSetTest extends TestCase {
+
+    public static void main(final String[] args) {
+        junit.textui.TestRunner.run(new TestSuite(DeweyOrderSetTest.class));
+    }
+
+    public static class Customer {
+        private String lastName;
+        private String firstName;
+        private String houseNumber;
+        private String streetName;
+        private String postalTown;
+
+        public String getLastName() {
+            return lastName;
+        }
+
+        public String getFirstName() {
+            return firstName;
+        }
+
+        public String getHouseNumber() {
+            return houseNumber;
+        }
+
+        public String getStreetName() {
+            return streetName;
+        }
+
+        public String getPostalTown() {
+            return postalTown;
+        }
+    }
+
+    private final FacetedMethod lastNameMember = FacetedMethod.createForProperty(Customer.class, "Last Name");
+    private final FacetedMethod firstNameMember = FacetedMethod.createForProperty(Customer.class, "First Name");
+    private final FacetedMethod houseNumberMember = FacetedMethod.createForProperty(Customer.class, "House Number");
+    private final FacetedMethod streetNameMember = FacetedMethod.createForProperty(Customer.class, "Street Name");
+    private final FacetedMethod postalTownMember = FacetedMethod.createForProperty(Customer.class, "Postal Town");
+    private final List<FacetedMethod> lastNameAndFirstName = ImmutableList.of(lastNameMember, firstNameMember);
+    private final List<FacetedMethod> nameAndAddressMembers = ImmutableList.of(lastNameMember, firstNameMember, houseNumberMember, streetNameMember, postalTownMember);
+    private final List<FacetedMethod> lastNameFirstNameAndPostalTown = ImmutableList.of(lastNameMember, firstNameMember, postalTownMember);
+
+    @Override
+    protected void setUp() {
+        LogManager.getLoggerRepository().setThreshold(Level.OFF);
+
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+    }
+
+    public void testDefaultGroup() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
+        assertEquals("", orderSet.getGroupName());
+        assertEquals("", orderSet.getGroupFullName());
+        assertEquals("", orderSet.getGroupPath());
+    }
+
+    public void testDefaultGroupSize() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
+        assertEquals(2, orderSet.size());
+        assertEquals(2, orderSet.elementList().size());
+        assertEquals(0, orderSet.children().size());
+    }
+
+    public void testDefaultGroupTwoMembersSorted() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
+        assertEquals(lastNameMember, orderSet.elementList().get(0));
+        assertEquals(firstNameMember, orderSet.elementList().get(1));
+    }
+
+    public void testTwoMembersAtDefaultGroupOtherWay() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", firstNameMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
+        assertEquals(firstNameMember, orderSet.elementList().get(0));
+        assertEquals(lastNameMember, orderSet.elementList().get(1));
+    }
+
+    public void testWithChildGroupDefaultGroupName() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
+        assertEquals("", orderSet.getGroupName());
+        assertEquals("", orderSet.getGroupFullName());
+        assertEquals("", orderSet.getGroupPath());
+    }
+
+    public void testWithChildGroupSize() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
+        assertEquals(1, orderSet.children().size());
+        assertEquals(3, orderSet.size());
+    }
+
+    public void testWithChildGroupChildsGroupName() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
+        final List<?> children = orderSet.children();
+        final OrderSet childOrderSet = (OrderSet) children.get(0);
+        assertEquals("Address", childOrderSet.getGroupName());
+        assertEquals("address", childOrderSet.getGroupFullName());
+        assertEquals("", childOrderSet.getGroupPath());
+    }
+
+    public void testWithChildGroupChildsGroupSize() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
+        final OrderSet childOrderSet = orderSet.children().get(0);
+        assertEquals(3, childOrderSet.size());
+        assertEquals(0, childOrderSet.children().size());
+    }
+
+    public void testWithChildGroupChildsGroupElementOrdering() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "6", houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "5", streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "4", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
+        final OrderSet childOrderSet = orderSet.children().get(0);
+        assertEquals(postalTownMember, childOrderSet.elementList().get(0));
+        assertEquals(streetNameMember, childOrderSet.elementList().get(1));
+        assertEquals(houseNumberMember, childOrderSet.elementList().get(2));
+    }
+
+    public void testWithChildGroupOrderedAtEnd() {
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "6", houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "5", streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "4", postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "3", lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", firstNameMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
+        assertEquals(firstNameMember, orderSet.elementList().get(0));
+        assertEquals(lastNameMember, orderSet.elementList().get(1));
+        assertTrue(orderSet.elementList().get(2) instanceof OrderSet);
+    }
+
+    public void testDefaultGroupNeitherAnnotatedSize() {
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
+        assertEquals(2, orderSet.elementList().size());
+    }
+
+    public void testDefaultGroupNeitherAnnotatedOrderedByName() {
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
+        assertEquals(firstNameMember, orderSet.elementList().get(0));
+        assertEquals(lastNameMember, orderSet.elementList().get(1));
+    }
+
+    public void testDefaultGroupMixOfAnnotatedAndNotSize() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "2", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameFirstNameAndPostalTown);
+        assertEquals(3, orderSet.elementList().size());
+    }
+
+    public void testDefaultGroupMixOfAnnotatedAndNotOrderedWithAnnotatedFirst() {
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", lastNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation("", "2", postalTownMember));
+
+        final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameFirstNameAndPostalTown);
+
+        assertEquals(lastNameMember, orderSet.elementList().get(0));
+        assertEquals(postalTownMember, orderSet.elementList().get(1));
+        assertEquals(firstNameMember, orderSet.elementList().get(2));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java
new file mode 100644
index 0000000..e4eb87b
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java
@@ -0,0 +1,118 @@
+/*
+ *  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.progmodel.facets.ordering.memberorder;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessMethodContext;
+import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.members.order.MemberOrderAnnotationFacetFactory;
+import org.apache.isis.core.progmodel.facets.members.order.MemberOrderFacetAnnotation;
+
+public class MemberOrderAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private MemberOrderAnnotationFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new MemberOrderAnnotationFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testMemberOrderAnnotationPickedUpOnProperty() {
+        class Customer {
+            @SuppressWarnings("unused")
+            @MemberOrder(sequence = "1")
+            public String getFirstName() {
+                return null;
+            }
+        }
+        final Method method = findMethod(Customer.class, "getFirstName");
+
+        facetFactory.process(new ProcessMethodContext(Customer.class, method, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(MemberOrderFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof MemberOrderFacetAnnotation);
+        final MemberOrderFacetAnnotation memberOrderFacetAnnotation = (MemberOrderFacetAnnotation) facet;
+        assertEquals("1", memberOrderFacetAnnotation.sequence());
+
+        assertNoMethodsRemoved();
+    }
+
+    public void testMemberOrderAnnotationPickedUpOnCollection() {
+        class Order {
+        }
+        class Customer {
+            @SuppressWarnings("unused")
+            @MemberOrder(sequence = "2")
+            public Collection<Order> getOrders() {
+                return null;
+            }
+
+            @SuppressWarnings("unused")
+            public void addToOrders(final Order o) {
+            }
+        }
+        final Method method = findMethod(Customer.class, "getOrders");
+
+        facetFactory.process(new ProcessMethodContext(Customer.class, method, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(MemberOrderFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof MemberOrderFacetAnnotation);
+        final MemberOrderFacetAnnotation memberOrderFacetAnnotation = (MemberOrderFacetAnnotation) facet;
+        assertEquals("2", memberOrderFacetAnnotation.sequence());
+
+        assertNoMethodsRemoved();
+    }
+
+    public void testMemberOrderAnnotationPickedUpOnAction() {
+        class Customer {
+            @SuppressWarnings("unused")
+            @MemberOrder(sequence = "3")
+            public void someAction() {
+            }
+        }
+        final Method method = findMethod(Customer.class, "someAction");
+
+        facetFactory.process(new ProcessMethodContext(Customer.class, method, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(MemberOrderFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof MemberOrderFacetAnnotation);
+        final MemberOrderFacetAnnotation memberOrderFacetAnnotation = (MemberOrderFacetAnnotation) facet;
+        assertEquals("3", memberOrderFacetAnnotation.sequence());
+
+        assertNoMethodsRemoved();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderComparatorTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderComparatorTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderComparatorTest.java
new file mode 100644
index 0000000..d50c4fb
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/ordering/memberorder/MemberOrderComparatorTest.java
@@ -0,0 +1,152 @@
+/*
+ *  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.progmodel.facets.ordering.memberorder;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderComparator;
+import org.apache.isis.core.progmodel.facets.members.order.MemberOrderFacetAnnotation;
+
+public class MemberOrderComparatorTest extends TestCase {
+
+    public static void main(final String[] args) {
+        junit.textui.TestRunner.run(new TestSuite(MemberOrderComparatorTest.class));
+    }
+
+    private MemberOrderComparator comparator, laxComparator;
+
+    public static class Customer {
+        private String abc;
+
+        public String getAbc() {
+            return abc;
+        }
+    }
+
+    private final FacetedMethod m1 = FacetedMethod.createForProperty(Customer.class, "abc");
+    private final FacetedMethod m2 = FacetedMethod.createForProperty(Customer.class, "abc");
+
+    @Override
+    protected void setUp() {
+        LogManager.getLoggerRepository().setThreshold(Level.OFF);
+
+        comparator = new MemberOrderComparator(true);
+        laxComparator = new MemberOrderComparator(false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+    }
+
+    public void testDefaultGroupOneComponent() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "2", m2));
+        assertEquals(-1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneComponentOtherWay() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "2", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1", m2));
+        assertEquals(+1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneComponentSame() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1", m2));
+        assertEquals(0, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsOutOfComponentsFirst() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1.1", m2));
+        assertEquals(-1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsOutOfComponentsFirstOtherWay() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1.1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1", m2));
+        assertEquals(+1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsTwoComponents() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1.1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2", m2));
+        assertEquals(-1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsTwoComponentsOtherWay() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1.1", m2));
+        assertEquals(+1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsLotsOfComponents() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.4", m2));
+        assertEquals(-1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsLotsOfComponentsOtherWay() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.4", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", m2));
+        assertEquals(+1, comparator.compare(m1, m2));
+    }
+
+    public void testDefaultGroupOneSideRunsLotsOfComponentsSame() {
+        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", m2));
+        assertEquals(0, comparator.compare(m1, m2));
+    }
+
+    public void testNamedGroupOneSideRunsLotsOfComponents() {
+        m1.addFacet(new MemberOrderFacetAnnotation("abc", "1.2.5.8.3.3", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("abc", "1.2.5.8.3.4", m2));
+        assertEquals(-1, comparator.compare(m1, m2));
+    }
+
+    public void testEnsuresInSameGroup() {
+        m1.addFacet(new MemberOrderFacetAnnotation("abc", "1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("def", "2", m2));
+        try {
+            assertEquals(-1, comparator.compare(m1, m2));
+            fail("Exception should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // expected
+        }
+    }
+
+    public void testEnsuresInSameGroupCanBeDisabled() {
+        m1.addFacet(new MemberOrderFacetAnnotation("abc", "1", m1));
+        m2.addFacet(new MemberOrderFacetAnnotation("def", "2", m2));
+        assertEquals(-1, laxComparator.compare(m1, m2));
+    }
+
+    public void testNonAnnotatedAfterAnnotated() {
+        // don't annotate m1
+        m2.addFacet(new MemberOrderFacetAnnotation("def", "2", m2));
+        assertEquals(+1, comparator.compare(m1, m2));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnCollectionFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnCollectionFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnCollectionFacetFactoryTest.java
new file mode 100644
index 0000000..76ddc3f
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnCollectionFacetFactoryTest.java
@@ -0,0 +1,90 @@
+/*
+ *  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.progmodel.facets.paged;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Paged;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessMethodContext;
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.facets.object.paged.PagedFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+
+public class PagedAnnotationOnCollectionFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private PagedAnnotationOnCollectionFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new PagedAnnotationOnCollectionFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    @Paged(20)
+    static class Customer {
+        @Paged(10)
+        public List<?> getOrders() {
+            return null;
+        }
+    }
+
+    static class CustomerWithoutPagedAnnotation {
+        public List<?> getOrders() {
+            return null;
+        }
+    }
+
+
+    public void testAnnotationPickedUpOnCollection() {
+        facetedMethod = FacetedMethod.createForCollection(Customer.class, "orders");
+        final Method method = facetedMethod.getMethod();
+        final ProcessMethodContext processMethodContext = new ProcessMethodContext(Customer.class, method, methodRemover, facetedMethod);
+        facetFactory.process(processMethodContext);
+
+        final Facet facet = facetedMethod.getFacet(PagedFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof PagedFacetAnnotation);
+        PagedFacet pagedFacet = (PagedFacet) facet;
+        assertThat(pagedFacet.value(), is(10));
+    }
+
+    public void testNoAnnotationOnCollection() {
+        facetedMethod = FacetedMethod.createForCollection(CustomerWithoutPagedAnnotation.class, "orders");
+        final Method method = facetedMethod.getMethod();
+        final ProcessMethodContext processMethodContext = new ProcessMethodContext(Customer.class, method, methodRemover, facetedMethod);
+        facetFactory.process(processMethodContext);
+
+        final Facet facet = facetedMethod.getFacet(PagedFacet.class);
+        assertNull(facet);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnTypeFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnTypeFacetFactoryTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnTypeFacetFactoryTest.java
new file mode 100644
index 0000000..b2754e9
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/paged/PagedAnnotationOnTypeFacetFactoryTest.java
@@ -0,0 +1,87 @@
+/*
+ *  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.progmodel.facets.paged;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Paged;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessMethodContext;
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.facets.object.paged.PagedFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+
+public class PagedAnnotationOnTypeFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private PagedAnnotationOnTypeFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new PagedAnnotationOnTypeFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    @Paged(20)
+    static class Customer {
+        @Paged(10)
+        public List<?> getOrders() {
+            return null;
+        }
+    }
+
+    static class CustomerWithoutPagedAnnotation {
+        public List<?> getOrders() {
+            return null;
+        }
+    }
+
+    public void testAnnotationPickedUpOnType() {
+        final ProcessClassContext processClassContext = new ProcessClassContext(Customer.class, methodRemover, facetHolder);
+        facetFactory.process(processClassContext);
+
+        final Facet facet = facetHolder.getFacet(PagedFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof PagedFacetAnnotation);
+        PagedFacet pagedFacet = (PagedFacet) facet;
+        assertThat(pagedFacet.value(), is(20));
+    }
+
+    public void testNoAnnotationOnType() {
+        final ProcessClassContext processClassContext = new ProcessClassContext(CustomerWithoutPagedAnnotation.class, methodRemover, facetHolder);
+        facetFactory.process(processClassContext);
+
+        final Facet facet = facetHolder.getFacet(PagedFacet.class);
+        assertNull(facet);
+    }
+
+
+}