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 2013/05/20 13:34:41 UTC

[1/8] ISIS-409: moving wrapper progmodel into core, as a service

Updated Branches:
  refs/heads/master 4329dc81d -> 55f931ae1


http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
new file mode 100644
index 0000000..e3f0dae
--- /dev/null
+++ b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
@@ -0,0 +1,153 @@
+/*
+ *  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.progmodel.wrapper;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.applib.services.wrapper.DisabledException;
+import org.apache.isis.applib.services.wrapper.HiddenException;
+import org.apache.isis.applib.services.wrapper.InvalidException;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.core.tck.dom.claimapp.employees.Employee;
+import org.apache.isis.core.tck.dom.claimapp.employees.EmployeeRepository;
+import org.apache.isis.core.tck.dom.claimapp.employees.EmployeeRepositoryImpl;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+
+public class WrappedFactoryDefaultTest_wrappedObject {
+
+    @Rule
+    public JUnitRuleMockery2 mockery = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY);
+
+    private EmployeeRepository employeeRepository;
+    // private ClaimRepository claimRepository;
+
+    private Employee employeeDO;
+    private Employee employeeWO;
+
+    private WrapperFactory wrapperFactory;
+
+    @Before
+    public void setUp() {
+
+        employeeRepository = new EmployeeRepositoryImpl();
+        // claimRepository = new ClaimRepositoryImpl();
+
+        employeeDO = new Employee();
+        employeeDO.setName("Smith");
+        employeeDO.setEmployeeRepository(employeeRepository); // would be done
+                                                              // by the
+                                                              // EmbeddedContext
+                                                              // impl
+
+        wrapperFactory = new WrapperFactoryDefault();
+        employeeWO = wrapperFactory.wrap(employeeDO);
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldWrapDomainObject() {
+        // then
+        assertThat(employeeWO, is(notNullValue()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldBeAbleToInjectIntoDomainObjects() {
+
+        // given
+        assertThat(employeeDO.getEmployeeRepository(), is(notNullValue()));
+
+        // then
+        assertThat(employeeWO.getEmployeeRepository(), is(notNullValue()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldBeAbleToReadVisibleProperty() {
+        // then
+        assertThat(employeeWO.getName(), is(employeeDO.getName()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = HiddenException.class)
+    public void shouldNotBeAbleToViewHiddenProperty() {
+        // given
+        employeeDO.whetherHideName = true;
+        // when
+        employeeWO.getName();
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldBeAbleToModifyEnabledPropertyUsingSetter() {
+        // when
+        employeeWO.setName("Jones");
+        // then
+        assertThat(employeeDO.getName(), is("Jones"));
+        assertThat(employeeWO.getName(), is(employeeDO.getName()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = DisabledException.class)
+    public void shouldNotBeAbleToModifyDisabledProperty() {
+        // given
+        employeeDO.reasonDisableName = "sorry, no change allowed";
+        // when
+        employeeWO.setName("Jones");
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = UnsupportedOperationException.class)
+    public void shouldNotBeAbleToModifyPropertyUsingModify() {
+        // when
+        employeeWO.modifyName("Jones");
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = UnsupportedOperationException.class)
+    public void shouldNotBeAbleToModifyPropertyUsingClear() {
+        // when
+        employeeWO.clearName();
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = InvalidException.class)
+    public void shouldNotBeAbleToModifyPropertyIfInvalid() {
+        // given
+        employeeDO.reasonValidateName = "sorry, invalid data";
+        // when
+        employeeWO.setName("Jones");
+        // then should throw exception
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
new file mode 100644
index 0000000..86b9173
--- /dev/null
+++ b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
@@ -0,0 +1,251 @@
+/*
+ *  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.progmodel.wrapper;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.services.wrapper.DisabledException;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.consent.Allow;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionResult;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
+import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacet;
+import org.apache.isis.core.progmodel.facets.members.disabled.staticmethod.DisabledFacetAlwaysEverywhere;
+import org.apache.isis.core.progmodel.facets.properties.accessor.PropertyAccessorFacetViaAccessor;
+import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaSetterMethod;
+import org.apache.isis.core.runtime.authentication.standard.SimpleSession;
+import org.apache.isis.core.tck.dom.claimapp.employees.Employee;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+
+public class WrappedFactoryDefaultTest_wrappedObject_transient {
+
+    @Rule
+    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private AdapterManager mockAdapterManager;
+    @Mock
+    private AuthenticationSessionProvider mockAuthenticationSessionProvider;
+    @Mock
+    private ObjectPersistor mockObjectPersistor;
+    @Mock
+    private SpecificationLoader mockSpecificationLookup;
+
+    private Employee employeeDO;
+    @Mock
+    private ObjectAdapter mockEmployeeAdapter;
+    @Mock
+    private ObjectSpecificationDefault mockEmployeeSpec;
+    @Mock
+    private OneToOneAssociation mockPasswordMember;
+    @Mock
+    private Identifier mockPasswordIdentifier;
+
+    @Mock
+    protected ObjectAdapter mockPasswordAdapter;
+    
+    private final String passwordValue = "12345678";
+
+    private final SimpleSession session = new SimpleSession("tester", Collections.<String>emptyList());
+
+    private List<Facet> facets;
+    private Method getPasswordMethod;
+    private Method setPasswordMethod;
+
+
+    private WrapperFactoryDefault wrapperFactory;
+    private Employee employeeWO;
+
+
+    @Before
+    public void setUp() throws Exception {
+
+        // employeeRepository = new EmployeeRepositoryImpl();
+        // claimRepository = new ClaimRepositoryImpl();
+
+        employeeDO = new Employee();
+        employeeDO.setName("Smith");
+        
+        getPasswordMethod = Employee.class.getMethod("getPassword");
+        setPasswordMethod = Employee.class.getMethod("setPassword", String.class);
+
+        wrapperFactory = new WrapperFactoryDefault();
+        wrapperFactory.setAdapterManager(mockAdapterManager);
+        wrapperFactory.setAuthenticationSessionProvider(mockAuthenticationSessionProvider);
+        wrapperFactory.setObjectPersistor(mockObjectPersistor);
+        wrapperFactory.setSpecificationLookup(mockSpecificationLookup);
+        
+        context.checking(new Expectations() {
+            {
+                allowing(mockAdapterManager).getAdapterFor(employeeDO);
+                will(returnValue(mockEmployeeAdapter));
+
+                allowing(mockAdapterManager).adapterFor(passwordValue);
+                will(returnValue(mockPasswordAdapter));
+
+                allowing(mockEmployeeAdapter).getSpecification();
+                will(returnValue(mockEmployeeSpec));
+
+                allowing(mockEmployeeAdapter).getObject();
+                will(returnValue(employeeDO));
+
+                allowing(mockPasswordAdapter).getObject();
+                will(returnValue(passwordValue));
+
+                allowing(mockPasswordMember).getIdentifier();
+                will(returnValue(mockPasswordIdentifier));
+
+                allowing(mockSpecificationLookup).loadSpecification(Employee.class);
+                will(returnValue(mockEmployeeSpec));
+                
+                allowing(mockEmployeeSpec).getMember(with(setPasswordMethod));
+                will(returnValue(mockPasswordMember));
+
+                allowing(mockEmployeeSpec).getMember(with(getPasswordMethod));
+                will(returnValue(mockPasswordMember));
+
+                allowing(mockPasswordMember).getName();
+                will(returnValue("password"));
+
+                allowing(mockAuthenticationSessionProvider).getAuthenticationSession();
+                will(returnValue(session));
+                
+                allowing(mockPasswordMember).isOneToOneAssociation();
+                will(returnValue(true));
+
+                allowing(mockPasswordMember).isOneToManyAssociation();
+                will(returnValue(false));
+            }
+        });
+
+        employeeWO = wrapperFactory.wrap(employeeDO);
+    }
+
+    @Test(expected = DisabledException.class)
+    public void shouldNotBeAbleToModifyProperty() {
+
+        // given
+        final DisabledFacet disabledFacet = new DisabledFacetAlwaysEverywhere(mockPasswordMember);
+        facets = Arrays.asList((Facet)disabledFacet, new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
+
+        final Consent visibilityConsent = new Allow(new InteractionResult(new PropertyVisibilityEvent(employeeDO, null)));
+
+        final InteractionResult usabilityInteractionResult = new InteractionResult(new PropertyUsabilityEvent(employeeDO, null));
+        usabilityInteractionResult.advise("disabled", disabledFacet);
+        final Consent usabilityConsent = new Veto(usabilityInteractionResult);
+
+        context.checking(new Expectations() {
+            {
+                allowing(mockPasswordMember).getFacets(with(any(Filter.class)));
+                will(returnValue(facets));
+                
+                allowing(mockPasswordMember).isVisible(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(visibilityConsent));
+                
+                allowing(mockPasswordMember).isUsable(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(usabilityConsent));
+            }
+        });
+        
+        // when
+        employeeWO.setPassword(passwordValue);
+        
+        // then should throw exception
+    }
+
+    @Test
+    public void canModifyProperty() {
+        // given
+
+        final Consent visibilityConsent = new Allow(new InteractionResult(new PropertyVisibilityEvent(employeeDO, mockPasswordIdentifier)));
+        final Consent usabilityConsent = new Allow(new InteractionResult(new PropertyUsabilityEvent(employeeDO, mockPasswordIdentifier)));
+        final Consent validityConsent = new Allow(new InteractionResult(new PropertyModifyEvent(employeeDO, mockPasswordIdentifier, passwordValue)));
+
+        context.checking(new Expectations() {
+            {
+                allowing(mockPasswordMember).isVisible(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(visibilityConsent));
+                
+                allowing(mockPasswordMember).isUsable(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(usabilityConsent));
+                
+                allowing(mockPasswordMember).isAssociationValid(mockEmployeeAdapter, mockPasswordAdapter);
+                will(returnValue(validityConsent));
+            }
+        });
+
+        facets = Arrays.asList((Facet)new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
+        context.checking(new Expectations() {
+            {
+                one(mockPasswordMember).getFacets(with(any(Filter.class)));
+                will(returnValue(facets));
+                
+                one(mockPasswordMember).set(mockEmployeeAdapter, mockPasswordAdapter);
+            }
+        });
+
+        // when
+        employeeWO.setPassword(passwordValue);
+
+
+        // and given
+        facets = Arrays.asList((Facet)new PropertyAccessorFacetViaAccessor(getPasswordMethod, mockPasswordMember));
+        context.checking(new Expectations() {
+            {
+                one(mockPasswordMember).getFacets(with(any(Filter.class)));
+                will(returnValue(facets));
+                
+                one(mockPasswordMember).get(mockEmployeeAdapter);
+                will(returnValue(mockPasswordAdapter));
+            }
+        });
+
+        // then be allowed
+        assertThat(employeeWO.getPassword(), is(passwordValue));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java b/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
index c5380b8..9455494 100644
--- a/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
+++ b/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
@@ -24,11 +24,11 @@ import org.junit.Before;
 import org.junit.runner.RunWith;
 
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
 import org.apache.isis.example.application.claims.dom.claim.ClaimRepository;
 import org.apache.isis.example.application.claims.dom.employee.Employee;
 import org.apache.isis.example.application.claims.dom.employee.EmployeeRepository;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
 import org.apache.isis.viewer.junit.IsisTestRunner;
 import org.apache.isis.viewer.junit.Service;
 import org.apache.isis.viewer.junit.Services;

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/ClaimSubmitTest.java
----------------------------------------------------------------------
diff --git a/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/ClaimSubmitTest.java b/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/ClaimSubmitTest.java
index 3922d39..d81b0d1 100644
--- a/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/ClaimSubmitTest.java
+++ b/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/ClaimSubmitTest.java
@@ -27,10 +27,10 @@ import java.util.List;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.services.wrapper.DisabledException;
 import org.apache.isis.example.application.claims.dom.claim.Approver;
 import org.apache.isis.example.application.claims.dom.claim.Claim;
 import org.apache.isis.example.application.claims.fixture.ClaimsFixture;
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
 import org.apache.isis.viewer.junit.Fixture;
 import org.apache.isis.viewer.junit.Fixtures;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java b/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
index 4c7dc79..b473cbe 100644
--- a/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
+++ b/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
@@ -26,8 +26,8 @@ import org.junit.Before;
 import org.junit.runner.RunWith;
 
 import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
 import org.apache.isis.viewer.junit.ConfigDir;
 import org.apache.isis.viewer.junit.IsisTestRunner;
 import org.apache.isis.viewer.junit.Service;

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/todo/ToDoItemTest.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/todo/ToDoItemTest.java b/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/todo/ToDoItemTest.java
index f13d70e..f299b32 100644
--- a/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/todo/ToDoItemTest.java
+++ b/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/todo/ToDoItemTest.java
@@ -30,7 +30,7 @@ import fixture.todo.ToDoItemsFixture;
 import org.junit.Before;
 import org.junit.Test;
 
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
+import org.apache.isis.applib.services.wrapper.DisabledException;
 import org.apache.isis.viewer.junit.Fixture;
 import org.apache.isis.viewer.junit.Fixtures;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7d66971..f2f0b21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,7 +52,6 @@
                 <module>component/objectstore/sql</module>
                 <module>component/objectstore/nosql</module>
                 <module>component/objectstore/jdo</module>
-                <module>component/progmodel/wrapper</module>
                 <module>component/progmodel/groovy</module>
         
                 <module>component/profilestore/xml</module>


[6/8] ISIS-409: fixing up build post moving wrapper service to core

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
deleted file mode 100644
index 66ce9eb..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.events.CollectionAccessEvent;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.ObjectTitleEvent;
-import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.applib.events.UsabilityEvent;
-import org.apache.isis.applib.events.ValidityEvent;
-import org.apache.isis.applib.events.VisibilityEvent;
-import org.apache.isis.applib.filter.Filter;
-import org.apache.isis.applib.services.wrapper.DisabledException;
-import org.apache.isis.applib.services.wrapper.HiddenException;
-import org.apache.isis.applib.services.wrapper.InteractionException;
-import org.apache.isis.applib.services.wrapper.InvalidException;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.WrapperObject;
-import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
-import org.apache.isis.core.metamodel.consent.InteractionResult;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facets.ImperativeFacet;
-import org.apache.isis.core.metamodel.facets.accessor.PropertyOrCollectionAccessorFacet;
-import org.apache.isis.core.metamodel.facets.actions.choices.ActionChoicesFacet;
-import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet;
-import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
-import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
-import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
-import org.apache.isis.core.metamodel.facets.properties.modify.PropertyInitializationFacet;
-import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
-import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
-import org.apache.isis.core.progmodel.facets.actions.validate.method.ActionValidationFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateRemoveFromFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.members.disabled.method.DisableForContextFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.members.hidden.method.HideForContextFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.properties.modify.PropertyClearFacetViaClearMethod;
-import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaModifyMethod;
-import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacetViaMethod;
-
-public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandlerDefault<T> {
-
-    private final Map<Method, Collection<?>> collectionViewObjectsByMethod = new HashMap<Method, Collection<?>>();
-    private final Map<Method, Map<?, ?>> mapViewObjectsByMethod = new HashMap<Method, Map<?, ?>>();
-
-    private final AuthenticationSessionProvider authenticationSessionProvider;
-    private final SpecificationLoader specificationLookup;
-    private final AdapterManager adapterManager;
-    private final ObjectPersistor objectPersistor;
-
-    /**
-     * The <tt>title()</tt> method; may be <tt>null</tt>.
-     */
-    protected Method titleMethod;
-
-    /**
-     * The <tt>save()</tt> method from {@link WrapperObject#save()}.
-     */
-    protected Method saveMethod;
-
-    /**
-     * The <tt>underlying()</tt> method from {@link WrapperObject#wrapped()}.
-     */
-    protected Method wrappedMethod;
-
-    public DomainObjectInvocationHandler(final T delegate, final WrapperFactory embeddedViewer, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager,
-            final ObjectPersistor objectPersistor) {
-        super(delegate, embeddedViewer, mode);
-
-        this.authenticationSessionProvider = authenticationSessionProvider;
-        this.specificationLookup = specificationLookup;
-        this.adapterManager = adapterManager;
-        this.objectPersistor = objectPersistor;
-
-        try {
-            titleMethod = delegate.getClass().getMethod("title", new Class[] {});
-            saveMethod = WrapperObject.class.getMethod("save", new Class[] {});
-            wrappedMethod = WrapperObject.class.getMethod("wrapped", new Class[] {});
-        } catch (final NoSuchMethodException e) {
-        }
-    }
-
-    @Override
-    public Object invoke(final Object proxyObject, final Method method, final Object[] args) throws Throwable {
-
-        if (isObjectMethod(method)) {
-            return delegate(method, args);
-        }
-
-        final ObjectAdapter targetAdapter = getAdapterManager().getAdapterFor(getDelegate());
-
-        if (isTitleMethod(method)) {
-            return handleTitleMethod(method, args, targetAdapter);
-        }
-
-        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
-
-        // save method, through the proxy
-        if (isSaveMethod(method)) {
-            return handleSaveMethod(getAuthenticationSession(), targetAdapter, targetNoSpec);
-        }
-
-        if (isUnderlyingMethod(method)) {
-            return getDelegate();
-        }
-
-        final ObjectMember objectMember = locateAndCheckMember(method);
-        final List<Facet> imperativeFacets = getImperativeFacets(objectMember, method);
-
-        final String memberName = objectMember.getName();
-
-        if (instanceOf(imperativeFacets, DisableForContextFacetViaMethod.class, HideForContextFacetViaMethod.class)) {
-            throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'", memberName));
-        }
-
-        final String methodName = method.getName();
-
-        if (instanceOf(imperativeFacets, ActionDefaultsFacet.class, PropertyDefaultFacet.class, ActionChoicesFacet.class, ActionParameterChoicesFacet.class, PropertyChoicesFacet.class)) {
-            return method.invoke(getDelegate(), args);
-        }
-
-        // for all members, check visibility and usability
-        checkVisibility(getAuthenticationSession(), targetAdapter, objectMember);
-
-        if (objectMember.isOneToOneAssociation()) {
-
-            if (instanceOf(imperativeFacets, PropertyValidateFacetViaMethod.class, PropertySetterFacetViaModifyMethod.class, PropertyClearFacetViaClearMethod.class)) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only property accessor/mutator", memberName));
-            }
-
-            final OneToOneAssociation otoa = (OneToOneAssociation) objectMember;
-            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
-                return handleGetterMethodOnProperty(args, targetAdapter, otoa, methodName);
-            }
-            if (instanceOf(imperativeFacets, PropertySetterFacet.class, PropertyInitializationFacet.class)) {
-                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-                return handleSetterMethodOnProperty(args, getAuthenticationSession(), targetAdapter, otoa, methodName);
-            }
-        }
-        if (objectMember.isOneToManyAssociation()) {
-
-            if (instanceOf(imperativeFacets, CollectionValidateAddToFacetViaMethod.class, CollectionValidateRemoveFromFacetViaMethod.class)) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only collection accessor/mutator", memberName));
-            }
-
-            final OneToManyAssociation otma = (OneToManyAssociation) objectMember;
-            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
-                return handleGetterMethodOnCollection(method, args, targetAdapter, otma, memberName);
-            }
-            if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
-                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-                return handleCollectionAddToMethod(args, targetAdapter, otma, methodName);
-            }
-            if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
-                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-                return handleCollectionRemoveFromMethod(args, targetAdapter, otma, methodName);
-            }
-        }
-
-        // filter out
-        if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke accessor on properties or collections; '%s' represents %s", methodName, decode(objectMember)));
-        }
-        if (instanceOf(imperativeFacets, PropertySetterFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke mutator on properties; '%s' represents %s", methodName, decode(objectMember)));
-        }
-        if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke 'adder' on collections; '%s' represents %s", methodName, decode(objectMember)));
-        }
-        if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke 'remover' on collections; '%s' represents %s", methodName, decode(objectMember)));
-        }
-
-        if (objectMember instanceof ObjectAction) {
-
-            if (instanceOf(imperativeFacets, ActionValidationFacetViaMethod.class)) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only the 'invoke' method", memberName));
-            }
-
-            checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-
-            final ObjectAction noa = (ObjectAction) objectMember;
-            return handleActionMethod(args, getAuthenticationSession(), targetAdapter, noa, memberName);
-        }
-
-        throw new UnsupportedOperationException(String.format("Unknown member type '%s'", objectMember));
-    }
-
-    public List<Facet> getImperativeFacets(final ObjectMember objectMember, final Method method) {
-        final List<Facet> imperativeFacets = objectMember.getFacets(new Filter<Facet>() {
-            @Override
-            public boolean accept(final Facet facet) {
-                final ImperativeFacet imperativeFacet = asImperativeFacet(facet);
-                if (imperativeFacet == null) {
-                    return false;
-                }
-                return imperativeFacet.getMethods().contains(method);
-            }
-
-            private ImperativeFacet asImperativeFacet(final Facet facet) {
-                if (facet == null) {
-                    return null;
-                }
-                if (facet instanceof ImperativeFacet) {
-                    return (ImperativeFacet) facet;
-                }
-                return asImperativeFacet(facet.getUnderlyingFacet());
-            }
-        });
-
-        // there will be at least one
-        if (imperativeFacets.isEmpty()) {
-            throw new IllegalStateException("should be at least one imperative facet");
-        }
-        return imperativeFacets;
-    }
-
-    private static boolean instanceOf(final List<?> objects, final Class<?>... superTypes) {
-        for (final Class<?> superType : superTypes) {
-            for (final Object obj : objects) {
-                if (superType.isAssignableFrom(obj.getClass())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // title
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleTitleMethod(final Method method, final Object[] args, final ObjectAdapter targetAdapter) throws IllegalAccessException, InvocationTargetException {
-
-        resolveIfRequired(targetAdapter);
-
-        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
-        final ObjectTitleContext titleContext = targetNoSpec.createTitleInteractionContext(getAuthenticationSession(), InteractionInvocationMethod.BY_USER, targetAdapter);
-        final ObjectTitleEvent titleEvent = titleContext.createInteractionEvent();
-        notifyListeners(titleEvent);
-        return titleEvent.getTitle();
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // save
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleSaveMethod(final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectSpecification targetNoSpec) {
-
-        final InteractionResult interactionResult = targetNoSpec.isValidResult(targetAdapter);
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            if (targetAdapter.isTransient()) {
-                getObjectPersistor().makePersistent(targetAdapter);
-            }
-        }
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // property - access
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleGetterMethodOnProperty(final Object[] args, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
-        if (args.length != 0) {
-            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final ObjectAdapter currentReferencedAdapter = otoa.get(targetAdapter);
-        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
-
-        final PropertyAccessEvent ev = new PropertyAccessEvent(getDelegate(), otoa.getIdentifier(), currentReferencedObj);
-        notifyListeners(ev);
-        return currentReferencedObj;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // property - modify
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleSetterMethodOnProperty(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
-        if (args.length != 1) {
-            throw new IllegalArgumentException("Invoking a setter should only have a single argument");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final Object argumentObj = underlying(args[0]);
-        final ObjectAdapter argumentAdapter = argumentObj != null ? getAdapterManager().adapterFor(argumentObj) : null;
-
-        final InteractionResult interactionResult = otoa.isAssociationValid(targetAdapter, argumentAdapter).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            otoa.set(targetAdapter, argumentAdapter);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // collection - access
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleGetterMethodOnCollection(final Method method, final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String memberName) {
-        if (args.length != 0) {
-            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final ObjectAdapter currentReferencedAdapter = otma.get(targetAdapter);
-        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
-
-        final CollectionAccessEvent ev = new CollectionAccessEvent(getDelegate(), otma.getIdentifier());
-
-        if (currentReferencedObj instanceof Collection) {
-            final Collection<?> collectionViewObject = lookupViewObject(method, memberName, (Collection<?>) currentReferencedObj, otma);
-            notifyListeners(ev);
-            return collectionViewObject;
-        } else if (currentReferencedObj instanceof Map) {
-            final Map<?, ?> mapViewObject = lookupViewObject(method, memberName, (Map<?, ?>) currentReferencedObj, otma);
-            notifyListeners(ev);
-            return mapViewObject;
-        }
-        throw new IllegalArgumentException(String.format("Collection type '%s' not supported by framework", currentReferencedObj.getClass().getName()));
-    }
-
-    /**
-     * Looks up (or creates) a proxy for this object.
-     */
-    private Collection<?> lookupViewObject(final Method method, final String memberName, final Collection<?> collectionToLookup, final OneToManyAssociation otma) {
-        Collection<?> collectionViewObject = collectionViewObjectsByMethod.get(method);
-        if (collectionViewObject == null) {
-            if (collectionToLookup instanceof WrapperObject) {
-                collectionViewObject = collectionToLookup;
-            } else {
-                collectionViewObject = Proxy.proxy(collectionToLookup, memberName, this, otma);
-            }
-            collectionViewObjectsByMethod.put(method, collectionViewObject);
-        }
-        return collectionViewObject;
-    }
-
-    private Map<?, ?> lookupViewObject(final Method method, final String memberName, final Map<?, ?> mapToLookup, final OneToManyAssociation otma) {
-        Map<?, ?> mapViewObject = mapViewObjectsByMethod.get(method);
-        if (mapViewObject == null) {
-            if (mapToLookup instanceof WrapperObject) {
-                mapViewObject = mapToLookup;
-            } else {
-                mapViewObject = Proxy.proxy(mapToLookup, memberName, this, otma);
-            }
-            mapViewObjectsByMethod.put(method, mapViewObject);
-        }
-        return mapViewObject;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // collection - add to
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleCollectionAddToMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
-
-        if (args.length != 1) {
-            throw new IllegalArgumentException("Invoking a addTo should only have a single argument");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final Object argumentObj = underlying(args[0]);
-        if (argumentObj == null) {
-            throw new IllegalArgumentException("Must provide a non-null object to add");
-        }
-        final ObjectAdapter argumentNO = getAdapterManager().adapterFor(argumentObj);
-
-        final InteractionResult interactionResult = otma.isValidToAdd(targetAdapter, argumentNO).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            otma.addElement(targetAdapter, argumentNO);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // collection - remove from
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleCollectionRemoveFromMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
-        if (args.length != 1) {
-            throw new IllegalArgumentException("Invoking a removeFrom should only have a single argument");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final Object argumentObj = underlying(args[0]);
-        if (argumentObj == null) {
-            throw new IllegalArgumentException("Must provide a non-null object to remove");
-        }
-        final ObjectAdapter argumentAdapter = getAdapterManager().adapterFor(argumentObj);
-
-        final InteractionResult interactionResult = otma.isValidToRemove(targetAdapter, argumentAdapter).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            otma.removeElement(targetAdapter, argumentAdapter);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // action
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleActionMethod(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectAction noa, final String memberName) {
-
-        final Object[] underlyingArgs = new Object[args.length];
-        int i = 0;
-        for (final Object arg : args) {
-            underlyingArgs[i++] = underlying(arg);
-        }
-
-        final ObjectAdapter[] argAdapters = new ObjectAdapter[underlyingArgs.length];
-        int j = 0;
-        for (final Object underlyingArg : underlyingArgs) {
-            argAdapters[j++] = underlyingArg != null ? getAdapterManager().adapterFor(underlyingArg) : null;
-        }
-
-        final InteractionResult interactionResult = noa.isProposedArgumentSetValid(targetAdapter, argAdapters).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            final ObjectAdapter actionReturnNO = noa.execute(targetAdapter, argAdapters);
-            return AdapterUtils.unwrap(actionReturnNO);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    private Object underlying(final Object arg) {
-        if (arg instanceof WrapperObject) {
-            final WrapperObject argViewObject = (WrapperObject) arg;
-            return argViewObject.wrapped();
-        } else {
-            return arg;
-        }
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // visibility and usability checks (common to all members)
-    // /////////////////////////////////////////////////////////////////
-
-    /**
-     * REVIEW: ideally should provide some way to allow to caller to indicate the 'where' context.  Having
-     * a hard-coded value like this is an approximation. 
-     */
-    private final Where where = Where.ANYWHERE;
-
-    private void checkVisibility(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
-        final Consent visibleConsent = objectMember.isVisible(getAuthenticationSession(), targetObjectAdapter, where);
-        final InteractionResult interactionResult = visibleConsent.getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-    }
-
-    private void checkUsability(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
-        final InteractionResult interactionResult = objectMember.isUsable(getAuthenticationSession(), targetObjectAdapter, where).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // notify listeners
-    // /////////////////////////////////////////////////////////////////
-
-    private void notifyListenersAndVetoIfRequired(final InteractionResult interactionResult) {
-        final InteractionEvent interactionEvent = interactionResult.getInteractionEvent();
-        notifyListeners(interactionEvent);
-        if (interactionEvent.isVeto()) {
-            throw toException(interactionEvent);
-        }
-    }
-
-    private String decode(final ObjectMember objectMember) {
-        if (objectMember instanceof OneToOneAssociation) {
-            return "a property";
-        }
-        if (objectMember instanceof OneToManyAssociation) {
-            return "a collection";
-        }
-        if (objectMember instanceof ObjectAction) {
-            return "an action";
-        }
-        return "an UNKNOWN member type";
-    }
-
-    /**
-     * Wraps a {@link InteractionEvent#isVeto() vetoing}
-     * {@link InteractionEvent} in a corresponding {@link InteractionException},
-     * and returns it.
-     */
-    private InteractionException toException(final InteractionEvent interactionEvent) {
-        if (!interactionEvent.isVeto()) {
-            throw new IllegalArgumentException("Provided interactionEvent must be a veto");
-        }
-        if (interactionEvent instanceof ValidityEvent) {
-            final ValidityEvent validityEvent = (ValidityEvent) interactionEvent;
-            return new InvalidException(validityEvent);
-        }
-        if (interactionEvent instanceof VisibilityEvent) {
-            final VisibilityEvent visibilityEvent = (VisibilityEvent) interactionEvent;
-            return new HiddenException(visibilityEvent);
-        }
-        if (interactionEvent instanceof UsabilityEvent) {
-            final UsabilityEvent usabilityEvent = (UsabilityEvent) interactionEvent;
-            return new DisabledException(usabilityEvent);
-        }
-        throw new IllegalArgumentException("Provided interactionEvent must be a VisibilityEvent, UsabilityEvent or a ValidityEvent");
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // switching
-    // /////////////////////////////////////////////////////////////////
-
-    private ObjectMember locateAndCheckMember(final Method method) {
-        final ObjectSpecificationDefault objectSpecificationDefault = getJavaSpecificationOfOwningClass(method);
-        final ObjectMember member = objectSpecificationDefault.getMember(method);
-        if (member == null) {
-            final String methodName = method.getName();
-            throw new UnsupportedOperationException("Method '" + methodName + "' being invoked does not correspond to any of the object's fields or actions.");
-        }
-        return member;
-    }
-
-    protected boolean isTitleMethod(final Method method) {
-        return method.equals(titleMethod);
-    }
-
-    protected boolean isSaveMethod(final Method method) {
-        return method.equals(saveMethod);
-    }
-
-    protected boolean isUnderlyingMethod(final Method method) {
-        return method.equals(wrappedMethod);
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // Specification lookup
-    // /////////////////////////////////////////////////////////////////
-
-    private ObjectSpecificationDefault getJavaSpecificationOfOwningClass(final Method method) {
-        return getJavaSpecification(method.getDeclaringClass());
-    }
-
-    private ObjectSpecificationDefault getJavaSpecification(final Class<?> clazz) {
-        final ObjectSpecification nos = getSpecification(clazz);
-        if (!(nos instanceof ObjectSpecificationDefault)) {
-            throw new UnsupportedOperationException("Only Java is supported (specification is '" + nos.getClass().getCanonicalName() + "')");
-        }
-        return (ObjectSpecificationDefault) nos;
-    }
-
-    private ObjectSpecification getSpecification(final Class<?> type) {
-        final ObjectSpecification nos = getSpecificationLookup().loadSpecification(type);
-        return nos;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // Dependencies
-    // /////////////////////////////////////////////////////////////////
-
-    protected SpecificationLoader getSpecificationLookup() {
-        return specificationLookup;
-    }
-
-    public AuthenticationSessionProvider getAuthenticationSessionProvider() {
-        return authenticationSessionProvider;
-    }
-
-    protected AuthenticationSession getAuthenticationSession() {
-        return getAuthenticationSessionProvider().getAuthenticationSession();
-    }
-
-    protected AdapterManager getAdapterManager() {
-        return adapterManager;
-    }
-
-    protected ObjectPersistor getObjectPersistor() {
-        return objectPersistor;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
deleted file mode 100644
index d551c72..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-/**
- * Used to instantiate a given class.
- */
-interface IClassInstantiatorCE {
-
-    /**
-     * Return a new instance of the specified class. The recommended way is
-     * without calling any constructor. This is usually done by doing like
-     * <code>ObjectInputStream.readObject()</code> which is JVM specific.
-     * 
-     * @param c
-     *            Class to instantiate
-     * @return new instance of clazz
-     */
-    Object newInstance(Class<?> clazz) throws InstantiationException;
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
deleted file mode 100644
index c92c0e8..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-
-public interface IProxyFactory<T> {
-    T createProxy(Class<T> toProxyClass, InvocationHandler handler);
-
-    T createProxy(T toProxy, InvocationHandler handler);
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
deleted file mode 100644
index 0515501..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import org.apache.isis.applib.events.InteractionEvent;
-
-public interface InteractionEventDispatcher {
-
-    void dispatch(InteractionEvent interactionEvent);
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
deleted file mode 100644
index 5ae80f6..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import org.apache.isis.applib.events.InteractionEvent;
-
-public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> implements InteractionEventDispatcher {
-
-    public abstract void dispatchTypeSafe(T interactionEvent);
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void dispatch(final InteractionEvent interactionEvent) {
-        dispatchTypeSafe((T) interactionEvent);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
deleted file mode 100644
index ebdcb52..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-public class InvocationHandlerMethodInterceptor implements MethodInterceptor {
-    private final InvocationHandler handler;
-
-    InvocationHandlerMethodInterceptor(final InvocationHandler handler) {
-        this.handler = handler;
-    }
-
-    @Override
-    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
-        return handler.invoke(obj, method, args);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
deleted file mode 100644
index e67a31d..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-import org.apache.isis.applib.services.wrapper.WrapperObject;
-
-public class JavaProxyFactory<T> implements IProxyFactory<T> {
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final T toProxy, final InvocationHandler handler) {
-        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
-        return (T) Proxy.newProxyInstance(proxyClass.getClassLoader(), new Class[] { proxyClass }, handler);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final Class<T> toProxy, final InvocationHandler handler) {
-        return (T) Proxy.newProxyInstance(toProxy.getClassLoader(), new Class[] { toProxy, WrapperObject.class }, handler);
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
deleted file mode 100644
index 779afac..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
-
-import java.util.Map;
-
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-class MapInvocationHandler<T, C> extends AbstractCollectionInvocationHandler<T, C> {
-
-    public MapInvocationHandler(final C collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionToProxy, collectionName, handler, otma);
-
-        try {
-            intercept(getMethod(collectionToProxy, "containsKey", Object.class));
-            intercept(getMethod(collectionToProxy, "containsValue", Object.class));
-            intercept(getMethod(collectionToProxy, "size"));
-            intercept(getMethod(collectionToProxy, "isEmpty"));
-            veto(getMethod(collectionToProxy, "put", Object.class, Object.class));
-            veto(getMethod(collectionToProxy, "remove", Object.class));
-            veto(getMethod(collectionToProxy, "putAll", Map.class));
-            veto(getMethod(collectionToProxy, "clear"));
-        } catch (final NoSuchMethodException e) {
-            // ///CLOVER:OFF
-            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
-            // ///CLOVER:ON
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
deleted file mode 100644
index 00028f1..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import org.objenesis.ObjenesisHelper;
-
-class ObjenesisClassInstantiatorCE implements IClassInstantiatorCE {
-
-    @Override
-    public Object newInstance(final Class<?> clazz) throws InstantiationException {
-        return ObjenesisHelper.newInstance(clazz);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
deleted file mode 100644
index 5008c2f..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.commons.ensure.Ensure;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-public class Proxy {
-
-    public static <T> T proxy(final T domainObject, final WrapperFactory wrapperFactory, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager, final ObjectPersistor objectPersistor) {
-
-        Ensure.ensureThatArg(wrapperFactory, is(not(nullValue())));
-        Ensure.ensureThatArg(authenticationSessionProvider, is(not(nullValue())));
-        Ensure.ensureThatArg(specificationLookup, is(not(nullValue())));
-        Ensure.ensureThatArg(adapterManager, is(not(nullValue())));
-        Ensure.ensureThatArg(objectPersistor, is(not(nullValue())));
-
-        final DomainObjectInvocationHandler<T> invocationHandler = new DomainObjectInvocationHandler<T>(domainObject, wrapperFactory, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
-
-        final CgLibProxy<T> cglibProxy = new CgLibProxy<T>(invocationHandler);
-        return cglibProxy.proxy();
-    }
-
-    /**
-     * Whether to execute or not will be picked up from the supplied parent
-     * handler.
-     */
-    public static <T, E> Collection<E> proxy(final Collection<E> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-
-        final CollectionInvocationHandler<T, Collection<E>> collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(collectionToProxy, collectionName, handler, otma);
-        collectionInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
-
-        final CgLibProxy<Collection<E>> cglibProxy = new CgLibProxy<Collection<E>>(collectionInvocationHandler);
-        return cglibProxy.proxy();
-    }
-
-    /**
-     * Whether to execute or not will be picked up from the supplied parent
-     * handler.
-     */
-    public static <T, P, Q> Map<P, Q> proxy(final Map<P, Q> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-
-        final MapInvocationHandler<T, Map<P, Q>> mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(collectionToProxy, collectionName, handler, otma);
-        mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
-
-        final CgLibProxy<Map<P, Q>> cglibProxy = new CgLibProxy<Map<P, Q>>(mapInvocationHandler);
-        return cglibProxy.proxy();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
deleted file mode 100644
index b6eae03..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-public class RuntimeExceptionWrapper extends RuntimeException {
-    private static final long serialVersionUID = 1L;
-    private final RuntimeException runtimeException;
-
-    public RuntimeExceptionWrapper(final RuntimeException runtimeException) {
-        this.runtimeException = runtimeException;
-    }
-
-    public RuntimeException getRuntimeException() {
-        return runtimeException;
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
deleted file mode 100644
index 4a51a03..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.isis.applib.events.ActionArgumentEvent;
-import org.apache.isis.applib.events.ActionInvocationEvent;
-import org.apache.isis.applib.events.ActionUsabilityEvent;
-import org.apache.isis.applib.events.ActionVisibilityEvent;
-import org.apache.isis.applib.events.CollectionAccessEvent;
-import org.apache.isis.applib.events.CollectionAddToEvent;
-import org.apache.isis.applib.events.CollectionMethodEvent;
-import org.apache.isis.applib.events.CollectionRemoveFromEvent;
-import org.apache.isis.applib.events.CollectionUsabilityEvent;
-import org.apache.isis.applib.events.CollectionVisibilityEvent;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.ObjectTitleEvent;
-import org.apache.isis.applib.events.ObjectValidityEvent;
-import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.applib.events.PropertyModifyEvent;
-import org.apache.isis.applib.events.PropertyUsabilityEvent;
-import org.apache.isis.applib.events.PropertyVisibilityEvent;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.WrapperObject;
-import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistorAware;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
-
-public class WrapperFactoryDefault implements WrapperFactory, AuthenticationSessionProviderAware, SpecificationLoaderAware, AdapterManagerAware, ObjectPersistorAware {
-
-    private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
-    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> dispatchersByEventClass = new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
-
-    private AuthenticationSessionProvider authenticationSessionProvider;
-    private SpecificationLoader specificationLookup;
-    private AdapterManager adapterManager;
-    private ObjectPersistor objectPersistor;
-
-    public WrapperFactoryDefault() {
-        dispatchersByEventClass.put(ObjectTitleEvent.class, new InteractionEventDispatcherTypeSafe<ObjectTitleEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ObjectTitleEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.objectTitleRead(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyAccessEvent.class, new InteractionEventDispatcherTypeSafe<PropertyAccessEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyAccessEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyAccessed(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyModifyEvent.class, new InteractionEventDispatcherTypeSafe<PropertyModifyEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyModifyEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyModified(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionAccessEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAccessEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionAccessEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionAccessed(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionAddToEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAddToEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionAddToEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionAddedTo(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionRemoveFromEvent.class, new InteractionEventDispatcherTypeSafe<CollectionRemoveFromEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionRemoveFromEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionRemovedFrom(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionArgumentEvent.class, new InteractionEventDispatcherTypeSafe<ActionArgumentEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionArgumentEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionArgument(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionInvocationEvent.class, new InteractionEventDispatcherTypeSafe<ActionInvocationEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionInvocationEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionInvoked(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ObjectValidityEvent.class, new InteractionEventDispatcherTypeSafe<ObjectValidityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ObjectValidityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.objectPersisted(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionMethodEvent.class, new InteractionEventDispatcherTypeSafe<CollectionMethodEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionMethodEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionMethodInvoked(interactionEvent);
-                }
-            }
-        });
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Views
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public <T> T wrap(final T domainObject) {
-        return wrap(domainObject, ExecutionMode.EXECUTE);
-    }
-
-    @Override
-    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
-        if (isWrapper(domainObject)) {
-            return domainObject;
-        }
-        return Proxy.proxy(domainObject, this, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
-    }
-
-    @Override
-    public boolean isWrapper(final Object possibleWrapper) {
-        return possibleWrapper instanceof WrapperObject;
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Listeners
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public List<InteractionListener> getListeners() {
-        return listeners;
-    }
-
-    @Override
-    public boolean addInteractionListener(final InteractionListener listener) {
-        return listeners.add(listener);
-    }
-
-    @Override
-    public boolean removeInteractionListener(final InteractionListener listener) {
-        return listeners.remove(listener);
-    }
-
-    @Override
-    public void notifyListeners(final InteractionEvent interactionEvent) {
-        final InteractionEventDispatcher dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
-        if (dispatcher == null) {
-            throw new RuntimeException("Unknown InteractionEvent - register into dispatchers map");
-        }
-        dispatcher.dispatch(interactionEvent);
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Listeners
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
-        this.authenticationSessionProvider = authenticationSessionProvider;
-    }
-
-    @Override
-    public void setAdapterManager(final AdapterManager adapterManager) {
-        this.adapterManager = adapterManager;
-    }
-
-    @Override
-    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
-        this.specificationLookup = specificationLookup;
-    }
-
-    @Override
-    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
-        this.objectPersistor = objectPersistor;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
deleted file mode 100644
index 2b743c5..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal.util;
-
-public final class Constants {
-    private Constants() {
-    }
-
-    public static final String PREFIX_CHOICES = "choices";
-    public static final String PREFIX_DEFAULT = "default";
-    public static final String PREFIX_HIDE = "hide";
-    public static final String PREFIX_DISABLE = "disable";
-    public static final String PREFIX_VALIDATE_REMOVE_FROM = "validateRemoveFrom";
-    public static final String PREFIX_VALIDATE_ADD_TO = "validateAddTo";
-    public static final String PREFIX_VALIDATE = "validate";
-    public static final String PREFIX_REMOVE_FROM = "removeFrom";
-    public static final String PREFIX_ADD_TO = "addTo";
-    public static final String PREFIX_MODIFY = "modify";
-    public static final String PREFIX_CLEAR = "clear";
-    public static final String PREFIX_SET = "set";
-    public static final String PREFIX_GET = "get";
-
-    public final static String TITLE_METHOD_NAME = "title";
-    public final static String TO_STRING_METHOD_NAME = "toString";
-
-    /**
-     * Cannot invoke methods with these prefixes.
-     */
-    public final static String[] INVALID_PREFIXES = { PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, };
-
-    public final static String[] PROPERTY_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
-    public final static String[] COLLECTION_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_ADD_TO, PREFIX_REMOVE_FROM, PREFIX_DISABLE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
-    public final static String[] ACTION_PREFIXES = { PREFIX_VALIDATE, PREFIX_DISABLE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES, };
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
deleted file mode 100644
index b2de21c..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal.util;
-
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-
-public final class MethodPrefixFinder {
-
-    // a Linked Hash Set is used to ensure that the ordering is preserved.
-    public final static LinkedHashSet<String> ALL_PREFIXES = new LinkedHashSet<String>() {
-        private static final long serialVersionUID = 1L;
-        {
-            // collection prefixes are added first because we want to
-            // test validateAddTo and validateRemoveFrom before validate
-            addAll(Arrays.asList(Constants.COLLECTION_PREFIXES));
-            addAll(Arrays.asList(Constants.PROPERTY_PREFIXES));
-            addAll(Arrays.asList(Constants.ACTION_PREFIXES));
-        }
-    };
-
-    public String findPrefix(final String methodName) {
-        for (final String prefix : ALL_PREFIXES) {
-            if (methodName.startsWith(prefix)) {
-                return prefix;
-            }
-        }
-        return "";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
index e3f0dae..5a5c653 100644
--- a/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
+++ b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
@@ -37,7 +37,7 @@ import org.apache.isis.core.tck.dom.claimapp.employees.EmployeeRepository;
 import org.apache.isis.core.tck.dom.claimapp.employees.EmployeeRepositoryImpl;
 import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
 
 public class WrappedFactoryDefaultTest_wrappedObject {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
index 86b9173..0b11f09 100644
--- a/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
+++ b/core/wrapper/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
@@ -60,7 +60,7 @@ import org.apache.isis.core.runtime.authentication.standard.SimpleSession;
 import org.apache.isis.core.tck.dom.claimapp.employees.Employee;
 import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
 
 public class WrappedFactoryDefaultTest_wrappedObject_transient {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java b/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
index 9455494..a1c6d38 100644
--- a/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
+++ b/example/application/claims/viewer-dnd/src/test/java/org/apache/isis/example/claims/junit/AbstractTest.java
@@ -26,6 +26,7 @@ import org.junit.runner.RunWith;
 import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
 import org.apache.isis.example.application.claims.dom.claim.ClaimRepository;
 import org.apache.isis.example.application.claims.dom.employee.Employee;
 import org.apache.isis.example.application.claims.dom.employee.EmployeeRepository;
@@ -34,7 +35,7 @@ import org.apache.isis.viewer.junit.Service;
 import org.apache.isis.viewer.junit.Services;
 
 @RunWith(IsisTestRunner.class)
-@Services({ @Service(ClaimRepository.class), @Service(EmployeeRepository.class) })
+@Services({ @Service(ClaimRepository.class), @Service(EmployeeRepository.class), @Service(WrapperFactoryDefault.class) })
 public abstract class AbstractTest {
 
     private DomainObjectContainer domainObjectContainer;

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java b/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
index b473cbe..e3ab772 100644
--- a/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
+++ b/example/application/quickstart_dnd_junit_bdd/tests-junit/src/test/java/junit/AbstractTest.java
@@ -28,6 +28,7 @@ import org.junit.runner.RunWith;
 import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
 import org.apache.isis.viewer.junit.ConfigDir;
 import org.apache.isis.viewer.junit.IsisTestRunner;
 import org.apache.isis.viewer.junit.Service;
@@ -35,7 +36,7 @@ import org.apache.isis.viewer.junit.Services;
 
 @RunWith(IsisTestRunner.class)
 @ConfigDir("../viewer-dnd/config") // acts as default, but can be overridden by annotations
-@Services({ @Service(ToDoItems.class) })
+@Services({ @Service(ToDoItems.class), @Service(WrapperFactoryDefault.class) })
 public abstract class AbstractTest {
 
     private DomainObjectContainer domainObjectContainer;


[4/8] ISIS-409: moving wrapper progmodel into core, as a service

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
deleted file mode 100644
index 5772b88..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-
-public interface DelegatingInvocationHandler<T> extends InvocationHandler {
-
-    T getDelegate();
-
-    public boolean isResolveObjectChangedEnabled();
-
-    public void setResolveObjectChangedEnabled(boolean resolveObjectChangedEnabled);
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
deleted file mode 100644
index e8cb309..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerObjectChanged;
-import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerResolve;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory.ExecutionMode;
-
-public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocationHandler<T> {
-
-    private final T delegate;
-    protected final WrapperFactory wrapperFactory;
-    private final ExecutionMode executionMode;
-
-    protected final Method equalsMethod;
-    protected final Method hashCodeMethod;
-    protected final Method toStringMethod;
-
-    private final DomainObjectContainerObjectChanged domainObjectContainerObjectChanged;
-    private final DomainObjectContainerResolve domainObjectContainerResolve;
-
-    private boolean resolveObjectChangedEnabled;
-
-    public DelegatingInvocationHandlerDefault(final T delegate, final WrapperFactory headlessViewer, final ExecutionMode executionMode) {
-        if (delegate == null) {
-            throw new IllegalArgumentException("delegate must not be null");
-        }
-        this.delegate = delegate;
-        this.wrapperFactory = headlessViewer;
-        this.executionMode = executionMode;
-
-        this.domainObjectContainerResolve = new DomainObjectContainerResolve();
-        this.domainObjectContainerObjectChanged = new DomainObjectContainerObjectChanged();
-
-        try {
-            equalsMethod = delegate.getClass().getMethod("equals", new Class[] { Object.class });
-            hashCodeMethod = delegate.getClass().getMethod("hashCode", new Class[] {});
-            toStringMethod = delegate.getClass().getMethod("toString", new Class[] {});
-        } catch (final NoSuchMethodException e) {
-            // ///CLOVER:OFF
-            throw new RuntimeException("An Object method could not be found: " + e.getMessage());
-            // ///CLOVER:ON
-        }
-    }
-
-    @Override
-    public boolean isResolveObjectChangedEnabled() {
-        return resolveObjectChangedEnabled;
-    }
-
-    @Override
-    public void setResolveObjectChangedEnabled(final boolean resolveObjectChangedEnabled) {
-        this.resolveObjectChangedEnabled = resolveObjectChangedEnabled;
-    }
-
-    protected void resolveIfRequired(final ObjectAdapter targetAdapter) {
-        resolveIfRequired(targetAdapter.getObject());
-    }
-
-    protected void resolveIfRequired(final Object domainObject) {
-        if (resolveObjectChangedEnabled) {
-            domainObjectContainerResolve.resolve(domainObject);
-        }
-    }
-
-    protected void objectChangedIfRequired(final ObjectAdapter targetAdapter) {
-        objectChangedIfRequired(targetAdapter.getObject());
-    }
-
-    protected void objectChangedIfRequired(final Object domainObject) {
-        if (resolveObjectChangedEnabled) {
-            domainObjectContainerObjectChanged.objectChanged(domainObject);
-        }
-    }
-
-    public WrapperFactory getHeadlessViewer() {
-        return wrapperFactory;
-    }
-
-    @Override
-    public T getDelegate() {
-        return delegate;
-    }
-
-    public ExecutionMode getExecutionMode() {
-        return executionMode;
-    }
-
-    protected Object delegate(final Method method, final Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-
-        return method.invoke(getDelegate(), args);
-    }
-
-    protected boolean isObjectMethod(final Method method) {
-        return toStringMethod.equals(method) || hashCodeMethod.equals(method) || equalsMethod.equals(method);
-    }
-
-    @Override
-    public Object invoke(final Object object, final Method method, final Object[] args) throws Throwable {
-        return method.invoke(object, args);
-    }
-
-    protected InteractionEvent notifyListeners(final InteractionEvent interactionEvent) {
-        wrapperFactory.notifyListeners(interactionEvent);
-        return interactionEvent;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
deleted file mode 100644
index fbc37f0..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.events.CollectionAccessEvent;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.ObjectTitleEvent;
-import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.applib.events.UsabilityEvent;
-import org.apache.isis.applib.events.ValidityEvent;
-import org.apache.isis.applib.events.VisibilityEvent;
-import org.apache.isis.applib.filter.Filter;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
-import org.apache.isis.core.metamodel.consent.InteractionResult;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facets.ImperativeFacet;
-import org.apache.isis.core.metamodel.facets.accessor.PropertyOrCollectionAccessorFacet;
-import org.apache.isis.core.metamodel.facets.actions.choices.ActionChoicesFacet;
-import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet;
-import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
-import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
-import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
-import org.apache.isis.core.metamodel.facets.properties.modify.PropertyInitializationFacet;
-import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
-import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
-import org.apache.isis.core.progmodel.facets.actions.validate.method.ActionValidationFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateRemoveFromFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.members.disabled.method.DisableForContextFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.members.hidden.method.HideForContextFacetViaMethod;
-import org.apache.isis.core.progmodel.facets.properties.modify.PropertyClearFacetViaClearMethod;
-import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaModifyMethod;
-import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacetViaMethod;
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
-import org.apache.isis.progmodel.wrapper.applib.HiddenException;
-import org.apache.isis.progmodel.wrapper.applib.InteractionException;
-import org.apache.isis.progmodel.wrapper.applib.InvalidException;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory.ExecutionMode;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
-
-public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandlerDefault<T> {
-
-    private final Map<Method, Collection<?>> collectionViewObjectsByMethod = new HashMap<Method, Collection<?>>();
-    private final Map<Method, Map<?, ?>> mapViewObjectsByMethod = new HashMap<Method, Map<?, ?>>();
-
-    private final AuthenticationSessionProvider authenticationSessionProvider;
-    private final SpecificationLoader specificationLookup;
-    private final AdapterManager adapterManager;
-    private final ObjectPersistor objectPersistor;
-
-    /**
-     * The <tt>title()</tt> method; may be <tt>null</tt>.
-     */
-    protected Method titleMethod;
-
-    /**
-     * The <tt>save()</tt> method from {@link WrapperObject#save()}.
-     */
-    protected Method saveMethod;
-
-    /**
-     * The <tt>underlying()</tt> method from {@link WrapperObject#wrapped()}.
-     */
-    protected Method wrappedMethod;
-
-    public DomainObjectInvocationHandler(final T delegate, final WrapperFactory embeddedViewer, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager,
-            final ObjectPersistor objectPersistor) {
-        super(delegate, embeddedViewer, mode);
-
-        this.authenticationSessionProvider = authenticationSessionProvider;
-        this.specificationLookup = specificationLookup;
-        this.adapterManager = adapterManager;
-        this.objectPersistor = objectPersistor;
-
-        try {
-            titleMethod = delegate.getClass().getMethod("title", new Class[] {});
-            saveMethod = WrapperObject.class.getMethod("save", new Class[] {});
-            wrappedMethod = WrapperObject.class.getMethod("wrapped", new Class[] {});
-        } catch (final NoSuchMethodException e) {
-        }
-    }
-
-    @Override
-    public Object invoke(final Object proxyObject, final Method method, final Object[] args) throws Throwable {
-
-        if (isObjectMethod(method)) {
-            return delegate(method, args);
-        }
-
-        final ObjectAdapter targetAdapter = getAdapterManager().getAdapterFor(getDelegate());
-
-        if (isTitleMethod(method)) {
-            return handleTitleMethod(method, args, targetAdapter);
-        }
-
-        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
-
-        // save method, through the proxy
-        if (isSaveMethod(method)) {
-            return handleSaveMethod(getAuthenticationSession(), targetAdapter, targetNoSpec);
-        }
-
-        if (isUnderlyingMethod(method)) {
-            return getDelegate();
-        }
-
-        final ObjectMember objectMember = locateAndCheckMember(method);
-        final List<Facet> imperativeFacets = getImperativeFacets(objectMember, method);
-
-        final String memberName = objectMember.getName();
-
-        if (instanceOf(imperativeFacets, DisableForContextFacetViaMethod.class, HideForContextFacetViaMethod.class)) {
-            throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'", memberName));
-        }
-
-        final String methodName = method.getName();
-
-        if (instanceOf(imperativeFacets, ActionDefaultsFacet.class, PropertyDefaultFacet.class, ActionChoicesFacet.class, ActionParameterChoicesFacet.class, PropertyChoicesFacet.class)) {
-            return method.invoke(getDelegate(), args);
-        }
-
-        // for all members, check visibility and usability
-        checkVisibility(getAuthenticationSession(), targetAdapter, objectMember);
-
-        if (objectMember.isOneToOneAssociation()) {
-
-            if (instanceOf(imperativeFacets, PropertyValidateFacetViaMethod.class, PropertySetterFacetViaModifyMethod.class, PropertyClearFacetViaClearMethod.class)) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only property accessor/mutator", memberName));
-            }
-
-            final OneToOneAssociation otoa = (OneToOneAssociation) objectMember;
-            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
-                return handleGetterMethodOnProperty(args, targetAdapter, otoa, methodName);
-            }
-            if (instanceOf(imperativeFacets, PropertySetterFacet.class, PropertyInitializationFacet.class)) {
-                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-                return handleSetterMethodOnProperty(args, getAuthenticationSession(), targetAdapter, otoa, methodName);
-            }
-        }
-        if (objectMember.isOneToManyAssociation()) {
-
-            if (instanceOf(imperativeFacets, CollectionValidateAddToFacetViaMethod.class, CollectionValidateRemoveFromFacetViaMethod.class)) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only collection accessor/mutator", memberName));
-            }
-
-            final OneToManyAssociation otma = (OneToManyAssociation) objectMember;
-            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
-                return handleGetterMethodOnCollection(method, args, targetAdapter, otma, memberName);
-            }
-            if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
-                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-                return handleCollectionAddToMethod(args, targetAdapter, otma, methodName);
-            }
-            if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
-                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-                return handleCollectionRemoveFromMethod(args, targetAdapter, otma, methodName);
-            }
-        }
-
-        // filter out
-        if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke accessor on properties or collections; '%s' represents %s", methodName, decode(objectMember)));
-        }
-        if (instanceOf(imperativeFacets, PropertySetterFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke mutator on properties; '%s' represents %s", methodName, decode(objectMember)));
-        }
-        if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke 'adder' on collections; '%s' represents %s", methodName, decode(objectMember)));
-        }
-        if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
-            throw new UnsupportedOperationException(String.format("Can only invoke 'remover' on collections; '%s' represents %s", methodName, decode(objectMember)));
-        }
-
-        if (objectMember instanceof ObjectAction) {
-
-            if (instanceOf(imperativeFacets, ActionValidationFacetViaMethod.class)) {
-                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only the 'invoke' method", memberName));
-            }
-
-            checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
-
-            final ObjectAction noa = (ObjectAction) objectMember;
-            return handleActionMethod(args, getAuthenticationSession(), targetAdapter, noa, memberName);
-        }
-
-        throw new UnsupportedOperationException(String.format("Unknown member type '%s'", objectMember));
-    }
-
-    public List<Facet> getImperativeFacets(final ObjectMember objectMember, final Method method) {
-        final List<Facet> imperativeFacets = objectMember.getFacets(new Filter<Facet>() {
-            @Override
-            public boolean accept(final Facet facet) {
-                final ImperativeFacet imperativeFacet = asImperativeFacet(facet);
-                if (imperativeFacet == null) {
-                    return false;
-                }
-                return imperativeFacet.getMethods().contains(method);
-            }
-
-            private ImperativeFacet asImperativeFacet(final Facet facet) {
-                if (facet == null) {
-                    return null;
-                }
-                if (facet instanceof ImperativeFacet) {
-                    return (ImperativeFacet) facet;
-                }
-                return asImperativeFacet(facet.getUnderlyingFacet());
-            }
-        });
-
-        // there will be at least one
-        if (imperativeFacets.isEmpty()) {
-            throw new IllegalStateException("should be at least one imperative facet");
-        }
-        return imperativeFacets;
-    }
-
-    private static boolean instanceOf(final List<?> objects, final Class<?>... superTypes) {
-        for (final Class<?> superType : superTypes) {
-            for (final Object obj : objects) {
-                if (superType.isAssignableFrom(obj.getClass())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // title
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleTitleMethod(final Method method, final Object[] args, final ObjectAdapter targetAdapter) throws IllegalAccessException, InvocationTargetException {
-
-        resolveIfRequired(targetAdapter);
-
-        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
-        final ObjectTitleContext titleContext = targetNoSpec.createTitleInteractionContext(getAuthenticationSession(), InteractionInvocationMethod.BY_USER, targetAdapter);
-        final ObjectTitleEvent titleEvent = titleContext.createInteractionEvent();
-        notifyListeners(titleEvent);
-        return titleEvent.getTitle();
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // save
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleSaveMethod(final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectSpecification targetNoSpec) {
-
-        final InteractionResult interactionResult = targetNoSpec.isValidResult(targetAdapter);
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            if (targetAdapter.isTransient()) {
-                getObjectPersistor().makePersistent(targetAdapter);
-            }
-        }
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // property - access
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleGetterMethodOnProperty(final Object[] args, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
-        if (args.length != 0) {
-            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final ObjectAdapter currentReferencedAdapter = otoa.get(targetAdapter);
-        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
-
-        final PropertyAccessEvent ev = new PropertyAccessEvent(getDelegate(), otoa.getIdentifier(), currentReferencedObj);
-        notifyListeners(ev);
-        return currentReferencedObj;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // property - modify
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleSetterMethodOnProperty(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
-        if (args.length != 1) {
-            throw new IllegalArgumentException("Invoking a setter should only have a single argument");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final Object argumentObj = underlying(args[0]);
-        final ObjectAdapter argumentAdapter = argumentObj != null ? getAdapterManager().adapterFor(argumentObj) : null;
-
-        final InteractionResult interactionResult = otoa.isAssociationValid(targetAdapter, argumentAdapter).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            otoa.set(targetAdapter, argumentAdapter);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // collection - access
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleGetterMethodOnCollection(final Method method, final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String memberName) {
-        if (args.length != 0) {
-            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final ObjectAdapter currentReferencedAdapter = otma.get(targetAdapter);
-        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
-
-        final CollectionAccessEvent ev = new CollectionAccessEvent(getDelegate(), otma.getIdentifier());
-
-        if (currentReferencedObj instanceof Collection) {
-            final Collection<?> collectionViewObject = lookupViewObject(method, memberName, (Collection<?>) currentReferencedObj, otma);
-            notifyListeners(ev);
-            return collectionViewObject;
-        } else if (currentReferencedObj instanceof Map) {
-            final Map<?, ?> mapViewObject = lookupViewObject(method, memberName, (Map<?, ?>) currentReferencedObj, otma);
-            notifyListeners(ev);
-            return mapViewObject;
-        }
-        throw new IllegalArgumentException(String.format("Collection type '%s' not supported by framework", currentReferencedObj.getClass().getName()));
-    }
-
-    /**
-     * Looks up (or creates) a proxy for this object.
-     */
-    private Collection<?> lookupViewObject(final Method method, final String memberName, final Collection<?> collectionToLookup, final OneToManyAssociation otma) {
-        Collection<?> collectionViewObject = collectionViewObjectsByMethod.get(method);
-        if (collectionViewObject == null) {
-            if (collectionToLookup instanceof WrapperObject) {
-                collectionViewObject = collectionToLookup;
-            } else {
-                collectionViewObject = Proxy.proxy(collectionToLookup, memberName, this, otma);
-            }
-            collectionViewObjectsByMethod.put(method, collectionViewObject);
-        }
-        return collectionViewObject;
-    }
-
-    private Map<?, ?> lookupViewObject(final Method method, final String memberName, final Map<?, ?> mapToLookup, final OneToManyAssociation otma) {
-        Map<?, ?> mapViewObject = mapViewObjectsByMethod.get(method);
-        if (mapViewObject == null) {
-            if (mapToLookup instanceof WrapperObject) {
-                mapViewObject = mapToLookup;
-            } else {
-                mapViewObject = Proxy.proxy(mapToLookup, memberName, this, otma);
-            }
-            mapViewObjectsByMethod.put(method, mapViewObject);
-        }
-        return mapViewObject;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // collection - add to
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleCollectionAddToMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
-
-        if (args.length != 1) {
-            throw new IllegalArgumentException("Invoking a addTo should only have a single argument");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final Object argumentObj = underlying(args[0]);
-        if (argumentObj == null) {
-            throw new IllegalArgumentException("Must provide a non-null object to add");
-        }
-        final ObjectAdapter argumentNO = getAdapterManager().adapterFor(argumentObj);
-
-        final InteractionResult interactionResult = otma.isValidToAdd(targetAdapter, argumentNO).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            otma.addElement(targetAdapter, argumentNO);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // collection - remove from
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleCollectionRemoveFromMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
-        if (args.length != 1) {
-            throw new IllegalArgumentException("Invoking a removeFrom should only have a single argument");
-        }
-
-        resolveIfRequired(targetAdapter);
-
-        final Object argumentObj = underlying(args[0]);
-        if (argumentObj == null) {
-            throw new IllegalArgumentException("Must provide a non-null object to remove");
-        }
-        final ObjectAdapter argumentAdapter = getAdapterManager().adapterFor(argumentObj);
-
-        final InteractionResult interactionResult = otma.isValidToRemove(targetAdapter, argumentAdapter).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            otma.removeElement(targetAdapter, argumentAdapter);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // action
-    // /////////////////////////////////////////////////////////////////
-
-    private Object handleActionMethod(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectAction noa, final String memberName) {
-
-        final Object[] underlyingArgs = new Object[args.length];
-        int i = 0;
-        for (final Object arg : args) {
-            underlyingArgs[i++] = underlying(arg);
-        }
-
-        final ObjectAdapter[] argAdapters = new ObjectAdapter[underlyingArgs.length];
-        int j = 0;
-        for (final Object underlyingArg : underlyingArgs) {
-            argAdapters[j++] = underlyingArg != null ? getAdapterManager().adapterFor(underlyingArg) : null;
-        }
-
-        final InteractionResult interactionResult = noa.isProposedArgumentSetValid(targetAdapter, argAdapters).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-
-        if (getExecutionMode() == ExecutionMode.EXECUTE) {
-            final ObjectAdapter actionReturnNO = noa.execute(targetAdapter, argAdapters);
-            return AdapterUtils.unwrap(actionReturnNO);
-        }
-
-        objectChangedIfRequired(targetAdapter);
-
-        return null;
-    }
-
-    private Object underlying(final Object arg) {
-        if (arg instanceof WrapperObject) {
-            final WrapperObject argViewObject = (WrapperObject) arg;
-            return argViewObject.wrapped();
-        } else {
-            return arg;
-        }
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // visibility and usability checks (common to all members)
-    // /////////////////////////////////////////////////////////////////
-
-    /**
-     * REVIEW: ideally should provide some way to allow to caller to indicate the 'where' context.  Having
-     * a hard-coded value like this is an approximation. 
-     */
-    private final Where where = Where.ANYWHERE;
-
-    private void checkVisibility(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
-        final Consent visibleConsent = objectMember.isVisible(getAuthenticationSession(), targetObjectAdapter, where);
-        final InteractionResult interactionResult = visibleConsent.getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-    }
-
-    private void checkUsability(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
-        final InteractionResult interactionResult = objectMember.isUsable(getAuthenticationSession(), targetObjectAdapter, where).getInteractionResult();
-        notifyListenersAndVetoIfRequired(interactionResult);
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // notify listeners
-    // /////////////////////////////////////////////////////////////////
-
-    private void notifyListenersAndVetoIfRequired(final InteractionResult interactionResult) {
-        final InteractionEvent interactionEvent = interactionResult.getInteractionEvent();
-        notifyListeners(interactionEvent);
-        if (interactionEvent.isVeto()) {
-            throw toException(interactionEvent);
-        }
-    }
-
-    private String decode(final ObjectMember objectMember) {
-        if (objectMember instanceof OneToOneAssociation) {
-            return "a property";
-        }
-        if (objectMember instanceof OneToManyAssociation) {
-            return "a collection";
-        }
-        if (objectMember instanceof ObjectAction) {
-            return "an action";
-        }
-        return "an UNKNOWN member type";
-    }
-
-    /**
-     * Wraps a {@link InteractionEvent#isVeto() vetoing}
-     * {@link InteractionEvent} in a corresponding {@link InteractionException},
-     * and returns it.
-     */
-    private InteractionException toException(final InteractionEvent interactionEvent) {
-        if (!interactionEvent.isVeto()) {
-            throw new IllegalArgumentException("Provided interactionEvent must be a veto");
-        }
-        if (interactionEvent instanceof ValidityEvent) {
-            final ValidityEvent validityEvent = (ValidityEvent) interactionEvent;
-            return new InvalidException(validityEvent);
-        }
-        if (interactionEvent instanceof VisibilityEvent) {
-            final VisibilityEvent visibilityEvent = (VisibilityEvent) interactionEvent;
-            return new HiddenException(visibilityEvent);
-        }
-        if (interactionEvent instanceof UsabilityEvent) {
-            final UsabilityEvent usabilityEvent = (UsabilityEvent) interactionEvent;
-            return new DisabledException(usabilityEvent);
-        }
-        throw new IllegalArgumentException("Provided interactionEvent must be a VisibilityEvent, UsabilityEvent or a ValidityEvent");
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // switching
-    // /////////////////////////////////////////////////////////////////
-
-    private ObjectMember locateAndCheckMember(final Method method) {
-        final ObjectSpecificationDefault objectSpecificationDefault = getJavaSpecificationOfOwningClass(method);
-        final ObjectMember member = objectSpecificationDefault.getMember(method);
-        if (member == null) {
-            final String methodName = method.getName();
-            throw new UnsupportedOperationException("Method '" + methodName + "' being invoked does not correspond to any of the object's fields or actions.");
-        }
-        return member;
-    }
-
-    protected boolean isTitleMethod(final Method method) {
-        return method.equals(titleMethod);
-    }
-
-    protected boolean isSaveMethod(final Method method) {
-        return method.equals(saveMethod);
-    }
-
-    protected boolean isUnderlyingMethod(final Method method) {
-        return method.equals(wrappedMethod);
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // Specification lookup
-    // /////////////////////////////////////////////////////////////////
-
-    private ObjectSpecificationDefault getJavaSpecificationOfOwningClass(final Method method) {
-        return getJavaSpecification(method.getDeclaringClass());
-    }
-
-    private ObjectSpecificationDefault getJavaSpecification(final Class<?> clazz) {
-        final ObjectSpecification nos = getSpecification(clazz);
-        if (!(nos instanceof ObjectSpecificationDefault)) {
-            throw new UnsupportedOperationException("Only Java is supported (specification is '" + nos.getClass().getCanonicalName() + "')");
-        }
-        return (ObjectSpecificationDefault) nos;
-    }
-
-    private ObjectSpecification getSpecification(final Class<?> type) {
-        final ObjectSpecification nos = getSpecificationLookup().loadSpecification(type);
-        return nos;
-    }
-
-    // /////////////////////////////////////////////////////////////////
-    // Dependencies
-    // /////////////////////////////////////////////////////////////////
-
-    protected SpecificationLoader getSpecificationLookup() {
-        return specificationLookup;
-    }
-
-    public AuthenticationSessionProvider getAuthenticationSessionProvider() {
-        return authenticationSessionProvider;
-    }
-
-    protected AuthenticationSession getAuthenticationSession() {
-        return getAuthenticationSessionProvider().getAuthenticationSession();
-    }
-
-    protected AdapterManager getAdapterManager() {
-        return adapterManager;
-    }
-
-    protected ObjectPersistor getObjectPersistor() {
-        return objectPersistor;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
deleted file mode 100644
index d551c72..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-/**
- * Used to instantiate a given class.
- */
-interface IClassInstantiatorCE {
-
-    /**
-     * Return a new instance of the specified class. The recommended way is
-     * without calling any constructor. This is usually done by doing like
-     * <code>ObjectInputStream.readObject()</code> which is JVM specific.
-     * 
-     * @param c
-     *            Class to instantiate
-     * @return new instance of clazz
-     */
-    Object newInstance(Class<?> clazz) throws InstantiationException;
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
deleted file mode 100644
index c92c0e8..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-
-public interface IProxyFactory<T> {
-    T createProxy(Class<T> toProxyClass, InvocationHandler handler);
-
-    T createProxy(T toProxy, InvocationHandler handler);
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
deleted file mode 100644
index 0515501..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import org.apache.isis.applib.events.InteractionEvent;
-
-public interface InteractionEventDispatcher {
-
-    void dispatch(InteractionEvent interactionEvent);
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
deleted file mode 100644
index 5ae80f6..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import org.apache.isis.applib.events.InteractionEvent;
-
-public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> implements InteractionEventDispatcher {
-
-    public abstract void dispatchTypeSafe(T interactionEvent);
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void dispatch(final InteractionEvent interactionEvent) {
-        dispatchTypeSafe((T) interactionEvent);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
deleted file mode 100644
index ebdcb52..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-public class InvocationHandlerMethodInterceptor implements MethodInterceptor {
-    private final InvocationHandler handler;
-
-    InvocationHandlerMethodInterceptor(final InvocationHandler handler) {
-        this.handler = handler;
-    }
-
-    @Override
-    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
-        return handler.invoke(obj, method, args);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
deleted file mode 100644
index 173d777..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
-
-public class JavaProxyFactory<T> implements IProxyFactory<T> {
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final T toProxy, final InvocationHandler handler) {
-        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
-        return (T) Proxy.newProxyInstance(proxyClass.getClassLoader(), new Class[] { proxyClass }, handler);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final Class<T> toProxy, final InvocationHandler handler) {
-        return (T) Proxy.newProxyInstance(toProxy.getClassLoader(), new Class[] { toProxy, WrapperObject.class }, handler);
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
deleted file mode 100644
index 779afac..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
-
-import java.util.Map;
-
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-class MapInvocationHandler<T, C> extends AbstractCollectionInvocationHandler<T, C> {
-
-    public MapInvocationHandler(final C collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionToProxy, collectionName, handler, otma);
-
-        try {
-            intercept(getMethod(collectionToProxy, "containsKey", Object.class));
-            intercept(getMethod(collectionToProxy, "containsValue", Object.class));
-            intercept(getMethod(collectionToProxy, "size"));
-            intercept(getMethod(collectionToProxy, "isEmpty"));
-            veto(getMethod(collectionToProxy, "put", Object.class, Object.class));
-            veto(getMethod(collectionToProxy, "remove", Object.class));
-            veto(getMethod(collectionToProxy, "putAll", Map.class));
-            veto(getMethod(collectionToProxy, "clear"));
-        } catch (final NoSuchMethodException e) {
-            // ///CLOVER:OFF
-            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
-            // ///CLOVER:ON
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
deleted file mode 100644
index 00028f1..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import org.objenesis.ObjenesisHelper;
-
-class ObjenesisClassInstantiatorCE implements IClassInstantiatorCE {
-
-    @Override
-    public Object newInstance(final Class<?> clazz) throws InstantiationException {
-        return ObjenesisHelper.newInstance(clazz);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
deleted file mode 100644
index dbcf4bb..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.commons.ensure.Ensure;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory.ExecutionMode;
-
-public class Proxy {
-
-    public static <T> T proxy(final T domainObject, final WrapperFactory wrapperFactory, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager, final ObjectPersistor objectPersistor) {
-
-        Ensure.ensureThatArg(wrapperFactory, is(not(nullValue())));
-        Ensure.ensureThatArg(authenticationSessionProvider, is(not(nullValue())));
-        Ensure.ensureThatArg(specificationLookup, is(not(nullValue())));
-        Ensure.ensureThatArg(adapterManager, is(not(nullValue())));
-        Ensure.ensureThatArg(objectPersistor, is(not(nullValue())));
-
-        final DomainObjectInvocationHandler<T> invocationHandler = new DomainObjectInvocationHandler<T>(domainObject, wrapperFactory, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
-
-        final CgLibProxy<T> cglibProxy = new CgLibProxy<T>(invocationHandler);
-        return cglibProxy.proxy();
-    }
-
-    /**
-     * Whether to execute or not will be picked up from the supplied parent
-     * handler.
-     */
-    public static <T, E> Collection<E> proxy(final Collection<E> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-
-        final CollectionInvocationHandler<T, Collection<E>> collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(collectionToProxy, collectionName, handler, otma);
-        collectionInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
-
-        final CgLibProxy<Collection<E>> cglibProxy = new CgLibProxy<Collection<E>>(collectionInvocationHandler);
-        return cglibProxy.proxy();
-    }
-
-    /**
-     * Whether to execute or not will be picked up from the supplied parent
-     * handler.
-     */
-    public static <T, P, Q> Map<P, Q> proxy(final Map<P, Q> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-
-        final MapInvocationHandler<T, Map<P, Q>> mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(collectionToProxy, collectionName, handler, otma);
-        mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
-
-        final CgLibProxy<Map<P, Q>> cglibProxy = new CgLibProxy<Map<P, Q>>(mapInvocationHandler);
-        return cglibProxy.proxy();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
deleted file mode 100644
index b6eae03..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-public class RuntimeExceptionWrapper extends RuntimeException {
-    private static final long serialVersionUID = 1L;
-    private final RuntimeException runtimeException;
-
-    public RuntimeExceptionWrapper(final RuntimeException runtimeException) {
-        this.runtimeException = runtimeException;
-    }
-
-    public RuntimeException getRuntimeException() {
-        return runtimeException;
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
deleted file mode 100644
index ad22797..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.isis.applib.events.ActionArgumentEvent;
-import org.apache.isis.applib.events.ActionInvocationEvent;
-import org.apache.isis.applib.events.ActionUsabilityEvent;
-import org.apache.isis.applib.events.ActionVisibilityEvent;
-import org.apache.isis.applib.events.CollectionAccessEvent;
-import org.apache.isis.applib.events.CollectionAddToEvent;
-import org.apache.isis.applib.events.CollectionMethodEvent;
-import org.apache.isis.applib.events.CollectionRemoveFromEvent;
-import org.apache.isis.applib.events.CollectionUsabilityEvent;
-import org.apache.isis.applib.events.CollectionVisibilityEvent;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.ObjectTitleEvent;
-import org.apache.isis.applib.events.ObjectValidityEvent;
-import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.applib.events.PropertyModifyEvent;
-import org.apache.isis.applib.events.PropertyUsabilityEvent;
-import org.apache.isis.applib.events.PropertyVisibilityEvent;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistorAware;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
-import org.apache.isis.progmodel.wrapper.applib.listeners.InteractionListener;
-
-public class WrapperFactoryDefault implements WrapperFactory, AuthenticationSessionProviderAware, SpecificationLoaderAware, AdapterManagerAware, ObjectPersistorAware {
-
-    private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
-    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> dispatchersByEventClass = new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
-
-    private AuthenticationSessionProvider authenticationSessionProvider;
-    private SpecificationLoader specificationLookup;
-    private AdapterManager adapterManager;
-    private ObjectPersistor objectPersistor;
-
-    public WrapperFactoryDefault() {
-        dispatchersByEventClass.put(ObjectTitleEvent.class, new InteractionEventDispatcherTypeSafe<ObjectTitleEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ObjectTitleEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.objectTitleRead(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyAccessEvent.class, new InteractionEventDispatcherTypeSafe<PropertyAccessEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyAccessEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyAccessed(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyModifyEvent.class, new InteractionEventDispatcherTypeSafe<PropertyModifyEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyModifyEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyModified(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionAccessEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAccessEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionAccessEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionAccessed(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionAddToEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAddToEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionAddToEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionAddedTo(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionRemoveFromEvent.class, new InteractionEventDispatcherTypeSafe<CollectionRemoveFromEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionRemoveFromEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionRemovedFrom(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionArgumentEvent.class, new InteractionEventDispatcherTypeSafe<ActionArgumentEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionArgumentEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionArgument(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionInvocationEvent.class, new InteractionEventDispatcherTypeSafe<ActionInvocationEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionInvocationEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionInvoked(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ObjectValidityEvent.class, new InteractionEventDispatcherTypeSafe<ObjectValidityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ObjectValidityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.objectPersisted(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionMethodEvent.class, new InteractionEventDispatcherTypeSafe<CollectionMethodEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionMethodEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionMethodInvoked(interactionEvent);
-                }
-            }
-        });
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Views
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public <T> T wrap(final T domainObject) {
-        return wrap(domainObject, ExecutionMode.EXECUTE);
-    }
-
-    @Override
-    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
-        if (isWrapper(domainObject)) {
-            return domainObject;
-        }
-        return Proxy.proxy(domainObject, this, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
-    }
-
-    @Override
-    public boolean isWrapper(final Object possibleWrapper) {
-        return possibleWrapper instanceof WrapperObject;
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Listeners
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public List<InteractionListener> getListeners() {
-        return listeners;
-    }
-
-    @Override
-    public boolean addInteractionListener(final InteractionListener listener) {
-        return listeners.add(listener);
-    }
-
-    @Override
-    public boolean removeInteractionListener(final InteractionListener listener) {
-        return listeners.remove(listener);
-    }
-
-    @Override
-    public void notifyListeners(final InteractionEvent interactionEvent) {
-        final InteractionEventDispatcher dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
-        if (dispatcher == null) {
-            throw new RuntimeException("Unknown InteractionEvent - register into dispatchers map");
-        }
-        dispatcher.dispatch(interactionEvent);
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Listeners
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
-        this.authenticationSessionProvider = authenticationSessionProvider;
-    }
-
-    @Override
-    public void setAdapterManager(final AdapterManager adapterManager) {
-        this.adapterManager = adapterManager;
-    }
-
-    @Override
-    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
-        this.specificationLookup = specificationLookup;
-    }
-
-    @Override
-    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
-        this.objectPersistor = objectPersistor;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
deleted file mode 100644
index 2b743c5..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal.util;
-
-public final class Constants {
-    private Constants() {
-    }
-
-    public static final String PREFIX_CHOICES = "choices";
-    public static final String PREFIX_DEFAULT = "default";
-    public static final String PREFIX_HIDE = "hide";
-    public static final String PREFIX_DISABLE = "disable";
-    public static final String PREFIX_VALIDATE_REMOVE_FROM = "validateRemoveFrom";
-    public static final String PREFIX_VALIDATE_ADD_TO = "validateAddTo";
-    public static final String PREFIX_VALIDATE = "validate";
-    public static final String PREFIX_REMOVE_FROM = "removeFrom";
-    public static final String PREFIX_ADD_TO = "addTo";
-    public static final String PREFIX_MODIFY = "modify";
-    public static final String PREFIX_CLEAR = "clear";
-    public static final String PREFIX_SET = "set";
-    public static final String PREFIX_GET = "get";
-
-    public final static String TITLE_METHOD_NAME = "title";
-    public final static String TO_STRING_METHOD_NAME = "toString";
-
-    /**
-     * Cannot invoke methods with these prefixes.
-     */
-    public final static String[] INVALID_PREFIXES = { PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, };
-
-    public final static String[] PROPERTY_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
-    public final static String[] COLLECTION_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_ADD_TO, PREFIX_REMOVE_FROM, PREFIX_DISABLE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
-    public final static String[] ACTION_PREFIXES = { PREFIX_VALIDATE, PREFIX_DISABLE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES, };
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
deleted file mode 100644
index b2de21c..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal.util;
-
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-
-public final class MethodPrefixFinder {
-
-    // a Linked Hash Set is used to ensure that the ordering is preserved.
-    public final static LinkedHashSet<String> ALL_PREFIXES = new LinkedHashSet<String>() {
-        private static final long serialVersionUID = 1L;
-        {
-            // collection prefixes are added first because we want to
-            // test validateAddTo and validateRemoveFrom before validate
-            addAll(Arrays.asList(Constants.COLLECTION_PREFIXES));
-            addAll(Arrays.asList(Constants.PROPERTY_PREFIXES));
-            addAll(Arrays.asList(Constants.ACTION_PREFIXES));
-        }
-    };
-
-    public String findPrefix(final String methodName) {
-        for (final String prefix : ALL_PREFIXES) {
-            if (methodName.startsWith(prefix)) {
-                return prefix;
-            }
-        }
-        return "";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt b/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt
deleted file mode 100644
index 1a1f4fa..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt
+++ /dev/null
@@ -1,22 +0,0 @@
-~~  Licensed to the Apache Software Foundation (ASF) under one
-~~  or more contributor license agreements.  See the NOTICE file
-~~  distributed with this work for additional information
-~~  regarding copyright ownership.  The ASF licenses this file
-~~  to you under the Apache License, Version 2.0 (the
-~~  "License"); you may not use this file except in compliance
-~~  with the License.  You may obtain a copy of the License at
-~~
-~~        http://www.apache.org/licenses/LICENSE-2.0
-~~
-~~  Unless required by applicable law or agreed to in writing,
-~~  software distributed under the License is distributed on an
-~~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-~~  KIND, either express or implied.  See the License for the
-~~  specific language governing permissions and limitations
-~~  under the License.
-
-
-
-Headless Viewer
- 
- The <headless viewer> module provides the main implementation of the headless viewer functionality.

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt b/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt
deleted file mode 100644
index c5d1200..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt
+++ /dev/null
@@ -1,24 +0,0 @@
-~~  Licensed to the Apache Software Foundation (ASF) under one
-~~  or more contributor license agreements.  See the NOTICE file
-~~  distributed with this work for additional information
-~~  regarding copyright ownership.  The ASF licenses this file
-~~  to you under the Apache License, Version 2.0 (the
-~~  "License"); you may not use this file except in compliance
-~~  with the License.  You may obtain a copy of the License at
-~~
-~~        http://www.apache.org/licenses/LICENSE-2.0
-~~
-~~  Unless required by applicable law or agreed to in writing,
-~~  software distributed under the License is distributed on an
-~~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-~~  KIND, either express or implied.  See the License for the
-~~  specific language governing permissions and limitations
-~~  under the License.
-
-
-
-Jottings
- 
-  This page is to capture any random jottings relating to this module prior 
-  to being moved into formal documentation. 
- 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml b/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml
deleted file mode 100644
index 6def7c8..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project>
-
-	<body>
-		<breadcrumbs>
-			<item name="Metamodel" href="index.html" />
-		</breadcrumbs>
-
-		<menu name="Wrapper Metamodel">
-			<item name="About" href="index.html" />
-            <item name="Jottings" href="jottings.html" />
-		</menu>
-
-        <menu name="Wrapper Modules">
-            <item name="Applib" href="../wrapper-applib/index.html" />
-            <item name="Metamodel" href="../wrapper-metamodel/index.html" />
-        </menu>
-
-        <menu name="Maven Reports" ref="reports" />
-	</body>
-</project>


[8/8] git commit: ISIS-409: fixing up build post moving wrapper service to core

Posted by da...@apache.org.
ISIS-409: fixing up build post moving wrapper service to core

* remove DomainObjectContainerWrapperFactory
* update junit viewer tests to explicitly register WrapperFactoryDefault
* prevent WrapperFactory interface hierarchy from being introspected into the Isis metamodel
* change package of wrapper service to o.a.i.core.wrapper


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/55f931ae
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/55f931ae
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/55f931ae

Branch: refs/heads/master
Commit: 55f931ae18086e372993d18f577eb69c66d4ec9f
Parents: cd0735d
Author: Dan Haywood <da...@apache.org>
Authored: Mon May 20 12:34:18 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Mon May 20 12:34:18 2013 +0100

----------------------------------------------------------------------
 .../viewer/junit/internal/AnnotationInstaller.java |    3 +-
 ...ryPersistenceMechanismInstallerWithinJunit.java |   37 -
 .../org/apache/isis/viewer/junit/AbstractTest.java |    3 +-
 .../tck/src/test/java/junit/AbstractTest.java      |    3 +-
 .../applib/services/wrapper/WrapperFactory.java    |    9 +
 .../AuthenticationSessionProvider.java             |    1 +
 .../AuthenticationSessionProviderAware.java        |    3 +
 .../isis/core/commons/components/Injectable.java   |    2 +
 .../metamodel/adapter/ObjectPersistorAware.java    |    3 +
 .../metamodel/adapter/mgr/AdapterManagerAware.java |    3 +
 .../metamodel/spec/SpecificationLoaderAware.java   |    3 +
 .../isis/core/wrapper/WrapperFactoryDefault.java   |  280 +++++++
 .../AbstractCollectionInvocationHandler.java       |   89 ++
 .../wrapper/internal/CgLibClassProxyFactory.java   |   71 ++
 .../isis/core/wrapper/internal/CgLibProxy.java     |   74 ++
 .../internal/ClassInstantiatorFactoryCE.java       |   65 ++
 .../internal/CollectionInvocationHandler.java      |   54 ++
 .../internal/DelegatingInvocationHandler.java      |   32 +
 .../DelegatingInvocationHandlerDefault.java        |  131 +++
 .../internal/DomainObjectInvocationHandler.java    |  645 +++++++++++++++
 .../wrapper/internal/IClassInstantiatorCE.java     |   37 +
 .../isis/core/wrapper/internal/IProxyFactory.java  |   28 +
 .../internal/InteractionEventDispatcher.java       |   28 +
 .../InteractionEventDispatcherTypeSafe.java        |   34 +
 .../InvocationHandlerMethodInterceptor.java        |   39 +
 .../core/wrapper/internal/JavaProxyFactory.java    |   40 +
 .../wrapper/internal/MapInvocationHandler.java     |   49 ++
 .../internal/ObjenesisClassInstantiatorCE.java     |   31 +
 .../apache/isis/core/wrapper/internal/Proxy.java   |   80 ++
 .../wrapper/internal/RuntimeExceptionWrapper.java  |   33 +
 .../isis/core/wrapper/internal/util/Constants.java |   52 ++
 .../wrapper/internal/util/MethodPrefixFinder.java  |   48 ++
 .../DomainObjectContainerWrapperFactory.java       |  116 ---
 .../AbstractCollectionInvocationHandler.java       |   89 --
 .../metamodel/internal/CgLibClassProxyFactory.java |   71 --
 .../wrapper/metamodel/internal/CgLibProxy.java     |   74 --
 .../internal/ClassInstantiatorFactoryCE.java       |   65 --
 .../internal/CollectionInvocationHandler.java      |   54 --
 .../internal/DelegatingInvocationHandler.java      |   32 -
 .../DelegatingInvocationHandlerDefault.java        |  131 ---
 .../internal/DomainObjectInvocationHandler.java    |  645 ---------------
 .../metamodel/internal/IClassInstantiatorCE.java   |   37 -
 .../wrapper/metamodel/internal/IProxyFactory.java  |   28 -
 .../internal/InteractionEventDispatcher.java       |   28 -
 .../InteractionEventDispatcherTypeSafe.java        |   34 -
 .../InvocationHandlerMethodInterceptor.java        |   39 -
 .../metamodel/internal/JavaProxyFactory.java       |   40 -
 .../metamodel/internal/MapInvocationHandler.java   |   49 --
 .../internal/ObjenesisClassInstantiatorCE.java     |   31 -
 .../wrapper/metamodel/internal/Proxy.java          |   80 --
 .../internal/RuntimeExceptionWrapper.java          |   33 -
 .../metamodel/internal/WrapperFactoryDefault.java  |  271 ------
 .../wrapper/metamodel/internal/util/Constants.java |   52 --
 .../internal/util/MethodPrefixFinder.java          |   48 --
 .../WrappedFactoryDefaultTest_wrappedObject.java   |    2 +-
 ...FactoryDefaultTest_wrappedObject_transient.java |    2 +-
 .../isis/example/claims/junit/AbstractTest.java    |    3 +-
 .../src/test/java/junit/AbstractTest.java          |    3 +-
 58 files changed, 1976 insertions(+), 2091 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/AnnotationInstaller.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/AnnotationInstaller.java b/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/AnnotationInstaller.java
index f61c20e..7c78163 100644
--- a/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/AnnotationInstaller.java
+++ b/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/AnnotationInstaller.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.viewer.junit.internal;
 
+import org.apache.isis.core.objectstore.InMemoryPersistenceMechanismInstaller;
 import org.apache.isis.core.runtime.authentication.AuthenticationManagerInstaller;
 import org.apache.isis.core.runtime.authorization.AuthorizationManagerInstaller;
 import org.apache.isis.core.runtime.installerregistry.installerapi.PersistenceMechanismInstaller;
@@ -79,7 +80,7 @@ public class AnnotationInstaller {
         if (annotation != null) {
             return addPersistorRepresentedBy(annotation);
         } else {
-            return new InMemoryPersistenceMechanismInstallerWithinJunit();
+            return new InMemoryPersistenceMechanismInstaller();
         }
 
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/InMemoryPersistenceMechanismInstallerWithinJunit.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/InMemoryPersistenceMechanismInstallerWithinJunit.java b/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/InMemoryPersistenceMechanismInstallerWithinJunit.java
deleted file mode 100644
index 6436f18..0000000
--- a/component/viewer/junit/impl/src/main/java/org/apache/isis/viewer/junit/internal/InMemoryPersistenceMechanismInstallerWithinJunit.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.viewer.junit.internal;
-
-import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.core.commons.config.IsisConfiguration;
-import org.apache.isis.core.objectstore.InMemoryPersistenceMechanismInstaller;
-import org.apache.isis.progmodel.wrapper.metamodel.DomainObjectContainerWrapperFactory;
-
-public class InMemoryPersistenceMechanismInstallerWithinJunit extends InMemoryPersistenceMechanismInstaller {
-
-    /**
-     * Returns a {@link DomainObjectContainerHeadlessViewer}.
-     */
-    @Override
-    public DomainObjectContainer createContainer(final IsisConfiguration configuration) {
-        return new DomainObjectContainerWrapperFactory();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
index bf87851..85a0027 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
@@ -25,6 +25,7 @@ import org.junit.runner.RunWith;
 
 import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
 import org.apache.isis.viewer.junit.sample.domain.Country;
 import org.apache.isis.viewer.junit.sample.domain.Customer;
 import org.apache.isis.viewer.junit.sample.domain.Product;
@@ -39,7 +40,7 @@ import org.apache.isis.viewer.junit.sample.service.ProductRepository;
 
 @RunWith(IsisTestRunner.class)
 @Fixtures({ @Fixture(CountriesFixture.class), @Fixture(ProductsFixture.class), @Fixture(CustomersFixture.class), @Fixture(CustomerOrdersFixture.class) })
-@Services({ @Service(CountryRepository.class), @Service(ProductRepository.class), @Service(CustomerRepository.class), @Service(OrderRepository.class) })
+@Services({ @Service(CountryRepository.class), @Service(ProductRepository.class), @Service(CustomerRepository.class), @Service(OrderRepository.class), @Service(WrapperFactoryDefault.class) })
 public abstract class AbstractTest {
 
     protected Customer custJsDO;

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java b/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
index 9924061..bf15176 100644
--- a/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
+++ b/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
@@ -27,6 +27,7 @@ import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.WrapperObject;
 import org.apache.isis.core.tck.dom.scalars.PrimitiveValuedEntityRepository;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
 import org.apache.isis.viewer.junit.ConfigDir;
 import org.apache.isis.viewer.junit.IsisTestRunner;
 import org.apache.isis.viewer.junit.Service;
@@ -34,7 +35,7 @@ import org.apache.isis.viewer.junit.Services;
 
 @RunWith(IsisTestRunner.class)
 @ConfigDir("../../viewer/dnd-tck/src/main/resources")
-@Services({ @Service(PrimitiveValuedEntityRepository.class) })
+@Services({ @Service(PrimitiveValuedEntityRepository.class), @Service(WrapperFactoryDefault.class) })
 public abstract class AbstractTest {
 
     private DomainObjectContainer domainObjectContainer;

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
index 317bbaa..e347c82 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
@@ -22,6 +22,7 @@ package org.apache.isis.applib.services.wrapper;
 import java.util.List;
 
 import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.events.InteractionEvent;
 import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
 
@@ -58,6 +59,7 @@ import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
  * <p>
  * An exception will be thrown if any other methods are thrown.
  */
+@Hidden
 public interface WrapperFactory {
 
     /**
@@ -79,6 +81,7 @@ public interface WrapperFactory {
      * 
      * @see #addInteractionListener(InteractionListener)
      */
+    @Programmatic
     <T> T wrap(T domainObject);
 
     /**
@@ -89,6 +92,7 @@ public interface WrapperFactory {
      * Otherwise, will do all the validations (raise exceptions as required
      * etc.), but doesn't modify the model.
      */
+    @Programmatic
     <T> T wrap(T domainObject, ExecutionMode mode);
 
     /**
@@ -99,12 +103,14 @@ public interface WrapperFactory {
      *            - object that might or might not be a wrapper.
      * @return
      */
+    @Programmatic
     <T> boolean isWrapper(T possibleWrapper);
 
     /**
      * All {@link InteractionListener}s that have been registered using
      * {@link #addInteractionListener(InteractionListener)}.
      */
+    @Programmatic
     List<InteractionListener> getListeners();
 
     /**
@@ -120,6 +126,7 @@ public interface WrapperFactory {
      * @param listener
      * @return
      */
+    @Programmatic
     public boolean addInteractionListener(InteractionListener listener);
 
     /**
@@ -135,8 +142,10 @@ public interface WrapperFactory {
      * @param listener
      * @return
      */
+    @Programmatic
     public boolean removeInteractionListener(InteractionListener listener);
 
+    @Programmatic
     public void notifyListeners(InteractionEvent ev);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProvider.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProvider.java
index d7cb01c..e302119 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.isis.core.commons.authentication;
 
+import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.commons.components.Injectable;
 
 public interface AuthenticationSessionProvider extends Injectable {

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProviderAware.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProviderAware.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProviderAware.java
index 9794d9b..39bd5a4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProviderAware.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/authentication/AuthenticationSessionProviderAware.java
@@ -19,8 +19,11 @@
 
 package org.apache.isis.core.commons.authentication;
 
+import org.apache.isis.applib.annotation.Programmatic;
+
 public interface AuthenticationSessionProviderAware {
 
+    @Programmatic
     public void setAuthenticationSessionProvider(AuthenticationSessionProvider authenticationSessionProvider);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/metamodel/src/main/java/org/apache/isis/core/commons/components/Injectable.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/components/Injectable.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/components/Injectable.java
index 225d77d..8356cbc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/components/Injectable.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/components/Injectable.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.commons.components;
 
+import org.apache.isis.applib.annotation.Programmatic;
+
 public interface Injectable {
 
     /**

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectPersistorAware.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectPersistorAware.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectPersistorAware.java
index 59e79d2..1a6cce3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectPersistorAware.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectPersistorAware.java
@@ -19,8 +19,11 @@
 
 package org.apache.isis.core.metamodel.adapter;
 
+import org.apache.isis.applib.annotation.Programmatic;
+
 public interface ObjectPersistorAware {
 
+    @Programmatic
     public void setObjectPersistor(final ObjectPersistor objectPersistor);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManagerAware.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManagerAware.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManagerAware.java
index d33c75e..ee52b48 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManagerAware.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManagerAware.java
@@ -19,9 +19,12 @@
 
 package org.apache.isis.core.metamodel.adapter.mgr;
 
+import org.apache.isis.applib.annotation.Programmatic;
+
 
 public interface AdapterManagerAware {
 
+    @Programmatic
     public void setAdapterManager(final AdapterManager adapterManager);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/SpecificationLoaderAware.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/SpecificationLoaderAware.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/SpecificationLoaderAware.java
index 9132f8c..5d925b2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/SpecificationLoaderAware.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/SpecificationLoaderAware.java
@@ -19,8 +19,11 @@
 
 package org.apache.isis.core.metamodel.spec;
 
+import org.apache.isis.applib.annotation.Programmatic;
+
 public interface SpecificationLoaderAware {
 
+    @Programmatic
     public void setSpecificationLookup(final SpecificationLoader specificationLookup);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java
new file mode 100644
index 0000000..b0cc78a
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java
@@ -0,0 +1,280 @@
+/*
+ *  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.wrapper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.events.ActionArgumentEvent;
+import org.apache.isis.applib.events.ActionInvocationEvent;
+import org.apache.isis.applib.events.ActionUsabilityEvent;
+import org.apache.isis.applib.events.ActionVisibilityEvent;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.CollectionAddToEvent;
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.CollectionRemoveFromEvent;
+import org.apache.isis.applib.events.CollectionUsabilityEvent;
+import org.apache.isis.applib.events.CollectionVisibilityEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.ObjectValidityEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistorAware;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
+import org.apache.isis.core.wrapper.internal.InteractionEventDispatcher;
+import org.apache.isis.core.wrapper.internal.InteractionEventDispatcherTypeSafe;
+import org.apache.isis.core.wrapper.internal.Proxy;
+
+public class WrapperFactoryDefault implements WrapperFactory, AuthenticationSessionProviderAware, SpecificationLoaderAware, AdapterManagerAware, ObjectPersistorAware {
+
+    private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
+    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> dispatchersByEventClass = new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
+
+    private AuthenticationSessionProvider authenticationSessionProvider;
+    private SpecificationLoader specificationLookup;
+    private AdapterManager adapterManager;
+    private ObjectPersistor objectPersistor;
+
+    public WrapperFactoryDefault() {
+        dispatchersByEventClass.put(ObjectTitleEvent.class, new InteractionEventDispatcherTypeSafe<ObjectTitleEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ObjectTitleEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.objectTitleRead(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyAccessEvent.class, new InteractionEventDispatcherTypeSafe<PropertyAccessEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyAccessEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyAccessed(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyModifyEvent.class, new InteractionEventDispatcherTypeSafe<PropertyModifyEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyModifyEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyModified(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionAccessEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAccessEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionAccessEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionAccessed(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionAddToEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAddToEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionAddToEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionAddedTo(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionRemoveFromEvent.class, new InteractionEventDispatcherTypeSafe<CollectionRemoveFromEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionRemoveFromEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionRemovedFrom(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionArgumentEvent.class, new InteractionEventDispatcherTypeSafe<ActionArgumentEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionArgumentEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionArgument(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionInvocationEvent.class, new InteractionEventDispatcherTypeSafe<ActionInvocationEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionInvocationEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionInvoked(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ObjectValidityEvent.class, new InteractionEventDispatcherTypeSafe<ObjectValidityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ObjectValidityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.objectPersisted(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionMethodEvent.class, new InteractionEventDispatcherTypeSafe<CollectionMethodEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionMethodEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionMethodInvoked(interactionEvent);
+                }
+            }
+        });
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Wrapped
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public <T> T wrap(final T domainObject) {
+        return wrap(domainObject, ExecutionMode.EXECUTE);
+    }
+
+    @Override
+    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
+        if (isWrapper(domainObject)) {
+            return domainObject;
+        }
+        return Proxy.proxy(domainObject, this, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
+    }
+
+    @Override
+    public boolean isWrapper(final Object possibleWrapper) {
+        return possibleWrapper instanceof WrapperObject;
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public List<InteractionListener> getListeners() {
+        return listeners;
+    }
+
+    @Override
+    public boolean addInteractionListener(final InteractionListener listener) {
+        return listeners.add(listener);
+    }
+
+    @Override
+    public boolean removeInteractionListener(final InteractionListener listener) {
+        return listeners.remove(listener);
+    }
+
+    @Override
+    public void notifyListeners(final InteractionEvent interactionEvent) {
+        final InteractionEventDispatcher dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
+        if (dispatcher == null) {
+            throw new RuntimeException("Unknown InteractionEvent - register into dispatchers map");
+        }
+        dispatcher.dispatch(interactionEvent);
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Programmatic
+    @Override
+    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
+        this.authenticationSessionProvider = authenticationSessionProvider;
+    }
+
+    @Programmatic
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    @Programmatic
+    @Override
+    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
+        this.specificationLookup = specificationLookup;
+    }
+
+    @Programmatic
+    @Override
+    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
+        this.objectPersistor = objectPersistor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/AbstractCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/AbstractCollectionInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/AbstractCollectionInvocationHandler.java
new file mode 100644
index 0000000..e5581d4
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/AbstractCollectionInvocationHandler.java
@@ -0,0 +1,89 @@
+/*
+ *  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.wrapper.internal;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+abstract class AbstractCollectionInvocationHandler<T, C> extends DelegatingInvocationHandlerDefault<C> {
+
+    private final List<Method> interceptedMethods = new ArrayList<Method>();
+    private final List<Method> vetoedMethods = new ArrayList<Method>();
+    private final String collectionName;
+    private final OneToManyAssociation oneToManyAssociation;
+    private final T domainObject;
+
+    public AbstractCollectionInvocationHandler(final C collectionOrMapToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionOrMapToProxy, handler.getHeadlessViewer(), handler.getExecutionMode());
+        this.collectionName = collectionName;
+        this.oneToManyAssociation = otma;
+        this.domainObject = handler.getDelegate();
+    }
+
+    protected Method intercept(final Method method) {
+        this.interceptedMethods.add(method);
+        return method;
+    }
+
+    protected Method veto(final Method method) {
+        this.vetoedMethods.add(method);
+        return method;
+    }
+
+    public String getCollectionName() {
+        return collectionName;
+    }
+
+    public OneToManyAssociation getCollection() {
+        return oneToManyAssociation;
+    }
+
+    public T getDomainObject() {
+        return domainObject;
+    }
+
+    @Override
+    public Object invoke(final Object collectionObject, final Method method, final Object[] args) throws Throwable {
+
+        // delegate
+        final Object returnValueObj = delegate(method, args);
+
+        if (interceptedMethods.contains(method)) {
+
+            resolveIfRequired(domainObject);
+
+            final InteractionEvent ev = new CollectionMethodEvent(getDelegate(), getCollection().getIdentifier(), getDomainObject(), method.getName(), args, returnValueObj);
+            notifyListeners(ev);
+            return returnValueObj;
+        }
+
+        if (vetoedMethods.contains(method)) {
+            throw new UnsupportedOperationException(String.format("Method '%s' may not be called directly.", method.getName()));
+        }
+
+        return returnValueObj;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibClassProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibClassProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibClassProxyFactory.java
new file mode 100644
index 0000000..8fb2b66
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibClassProxyFactory.java
@@ -0,0 +1,71 @@
+/*
+ *  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.wrapper.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+
+/**
+ * Factory generating a mock for a class.
+ * <p>
+ * Note that this class is stateful
+ */
+public class CgLibClassProxyFactory<T> implements IProxyFactory<T> {
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final T toProxy, final InvocationHandler handler) {
+        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
+        return createProxy(proxyClass, handler);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final Class<T> toProxyClass, final InvocationHandler handler) {
+
+        final MethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
+
+        // Create the proxy
+        final Enhancer enhancer = new Enhancer();
+        enhancer.setSuperclass(toProxyClass);
+        enhancer.setInterfaces(new Class[] { WrapperObject.class });
+        enhancer.setCallbackType(interceptor.getClass());
+
+        final Class<?> enhancedClass = enhancer.createClass();
+
+        Enhancer.registerCallbacks(enhancedClass, new Callback[] { interceptor });
+
+        Factory factory;
+        try {
+            factory = (Factory) ClassInstantiatorFactoryCE.getInstantiator().newInstance(enhancedClass);
+        } catch (final InstantiationException e) {
+            throw new RuntimeException("Fail to instantiate mock for " + toProxyClass + " on " + ClassInstantiatorFactoryCE.getJVM() + " JVM");
+        }
+
+        return (T) factory;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibProxy.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibProxy.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibProxy.java
new file mode 100644
index 0000000..ec432cc
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CgLibProxy.java
@@ -0,0 +1,74 @@
+/*
+ *  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.wrapper.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.core.metamodel.specloader.classsubstitutor.CglibEnhanced;
+
+public class CgLibProxy<T> {
+
+    private final DelegatingInvocationHandler<T> handler;
+
+    public CgLibProxy(final DelegatingInvocationHandler<T> handler) {
+        this.handler = handler;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T proxy() {
+
+        final T toProxy = handler.getDelegate();
+
+        // handle if already proxied using cglib.
+        if (CglibEnhanced.class.isAssignableFrom(toProxy.getClass())) {
+
+            handler.setResolveObjectChangedEnabled(true);
+
+            final Class<? extends Object> enhancedClass = toProxy.getClass();
+            final Class<? extends Object> origSuperclass = toProxy.getClass().getSuperclass();
+
+            final List<Class> interfaces = new ArrayList<Class>();
+            interfaces.addAll(Arrays.asList(enhancedClass.getInterfaces()));
+            interfaces.remove(Factory.class); // if there.
+            interfaces.add(WrapperObject.class);
+
+            InvocationHandlerMethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
+            return (T) Enhancer.create(origSuperclass, interfaces.toArray(new Class[] {}), interceptor);
+        }
+
+        final Class<T> clazz = (Class<T>) toProxy.getClass();
+
+        T proxy = null;
+        try {
+            final IProxyFactory<T> proxyFactory = clazz.isInterface() ? new JavaProxyFactory<T>() : new CgLibClassProxyFactory<T>();
+            proxy = proxyFactory.createProxy(clazz, handler);
+        } catch (final RuntimeExceptionWrapper e) {
+            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+        }
+        return proxy;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ClassInstantiatorFactoryCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ClassInstantiatorFactoryCE.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ClassInstantiatorFactoryCE.java
new file mode 100644
index 0000000..465daf2
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ClassInstantiatorFactoryCE.java
@@ -0,0 +1,65 @@
+/*
+ *  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.wrapper.internal;
+
+/**
+ * Factory returning a {@link IClassInstantiatorCE}for the current JVM
+ */
+class ClassInstantiatorFactoryCE {
+
+    private static IClassInstantiatorCE instantiator = new ObjenesisClassInstantiatorCE();
+
+    // ///CLOVER:OFF
+    private ClassInstantiatorFactoryCE() {
+    }
+
+    // ///CLOVER:ON
+
+    /**
+     * Returns the current JVM as specified in the Systtem properties
+     * 
+     * @return current JVM
+     */
+    public static String getJVM() {
+        return System.getProperty("java.vm.vendor");
+    }
+
+    /**
+     * Returns the current JVM specification version (1.5, 1.4, 1.3)
+     * 
+     * @return current JVM specification version
+     */
+    public static String getJVMSpecificationVersion() {
+        return System.getProperty("java.specification.version");
+    }
+
+    public static boolean is1_3Specifications() {
+        return getJVMSpecificationVersion().equals("1.3");
+    }
+
+    /**
+     * Returns a class instantiator suitable for the current JVM
+     * 
+     * @return a class instantiator usable on the current JVM
+     */
+    public static IClassInstantiatorCE getInstantiator() {
+        return instantiator;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CollectionInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CollectionInvocationHandler.java
new file mode 100644
index 0000000..979df43
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/CollectionInvocationHandler.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.wrapper.internal;
+
+import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+class CollectionInvocationHandler<T, R> extends AbstractCollectionInvocationHandler<T, R> {
+
+    public CollectionInvocationHandler(final R collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionToProxy, collectionName, handler, otma);
+
+        try {
+            intercept(getMethod(collectionToProxy, "contains", Object.class));
+            intercept(getMethod(collectionToProxy, "size"));
+            intercept(getMethod(collectionToProxy, "isEmpty"));
+            if (collectionToProxy instanceof List) {
+                intercept(getMethod(collectionToProxy, "get", int.class));
+            }
+            veto(getMethod(collectionToProxy, "add", Object.class));
+            veto(getMethod(collectionToProxy, "remove", Object.class));
+            veto(getMethod(collectionToProxy, "addAll", Collection.class));
+            veto(getMethod(collectionToProxy, "removeAll", Collection.class));
+            veto(getMethod(collectionToProxy, "retainAll", Collection.class));
+            veto(getMethod(collectionToProxy, "clear"));
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandler.java
new file mode 100644
index 0000000..44b3204
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandler.java
@@ -0,0 +1,32 @@
+/*
+ *  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.wrapper.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+public interface DelegatingInvocationHandler<T> extends InvocationHandler {
+
+    T getDelegate();
+
+    public boolean isResolveObjectChangedEnabled();
+
+    public void setResolveObjectChangedEnabled(boolean resolveObjectChangedEnabled);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandlerDefault.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandlerDefault.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandlerDefault.java
new file mode 100644
index 0000000..337853e
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DelegatingInvocationHandlerDefault.java
@@ -0,0 +1,131 @@
+/*
+ *  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.wrapper.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerObjectChanged;
+import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerResolve;
+
+public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocationHandler<T> {
+
+    private final T delegate;
+    protected final WrapperFactory wrapperFactory;
+    private final ExecutionMode executionMode;
+
+    protected final Method equalsMethod;
+    protected final Method hashCodeMethod;
+    protected final Method toStringMethod;
+
+    private final DomainObjectContainerObjectChanged domainObjectContainerObjectChanged;
+    private final DomainObjectContainerResolve domainObjectContainerResolve;
+
+    private boolean resolveObjectChangedEnabled;
+
+    public DelegatingInvocationHandlerDefault(final T delegate, final WrapperFactory headlessViewer, final ExecutionMode executionMode) {
+        if (delegate == null) {
+            throw new IllegalArgumentException("delegate must not be null");
+        }
+        this.delegate = delegate;
+        this.wrapperFactory = headlessViewer;
+        this.executionMode = executionMode;
+
+        this.domainObjectContainerResolve = new DomainObjectContainerResolve();
+        this.domainObjectContainerObjectChanged = new DomainObjectContainerObjectChanged();
+
+        try {
+            equalsMethod = delegate.getClass().getMethod("equals", new Class[] { Object.class });
+            hashCodeMethod = delegate.getClass().getMethod("hashCode", new Class[] {});
+            toStringMethod = delegate.getClass().getMethod("toString", new Class[] {});
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("An Object method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+    @Override
+    public boolean isResolveObjectChangedEnabled() {
+        return resolveObjectChangedEnabled;
+    }
+
+    @Override
+    public void setResolveObjectChangedEnabled(final boolean resolveObjectChangedEnabled) {
+        this.resolveObjectChangedEnabled = resolveObjectChangedEnabled;
+    }
+
+    protected void resolveIfRequired(final ObjectAdapter targetAdapter) {
+        resolveIfRequired(targetAdapter.getObject());
+    }
+
+    protected void resolveIfRequired(final Object domainObject) {
+        if (resolveObjectChangedEnabled) {
+            domainObjectContainerResolve.resolve(domainObject);
+        }
+    }
+
+    protected void objectChangedIfRequired(final ObjectAdapter targetAdapter) {
+        objectChangedIfRequired(targetAdapter.getObject());
+    }
+
+    protected void objectChangedIfRequired(final Object domainObject) {
+        if (resolveObjectChangedEnabled) {
+            domainObjectContainerObjectChanged.objectChanged(domainObject);
+        }
+    }
+
+    public WrapperFactory getHeadlessViewer() {
+        return wrapperFactory;
+    }
+
+    @Override
+    public T getDelegate() {
+        return delegate;
+    }
+
+    public ExecutionMode getExecutionMode() {
+        return executionMode;
+    }
+
+    protected Object delegate(final Method method, final Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+
+        return method.invoke(getDelegate(), args);
+    }
+
+    protected boolean isObjectMethod(final Method method) {
+        return toStringMethod.equals(method) || hashCodeMethod.equals(method) || equalsMethod.equals(method);
+    }
+
+    @Override
+    public Object invoke(final Object object, final Method method, final Object[] args) throws Throwable {
+        return method.invoke(object, args);
+    }
+
+    protected InteractionEvent notifyListeners(final InteractionEvent interactionEvent) {
+        wrapperFactory.notifyListeners(interactionEvent);
+        return interactionEvent;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DomainObjectInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DomainObjectInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DomainObjectInvocationHandler.java
new file mode 100644
index 0000000..6caf76e
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/DomainObjectInvocationHandler.java
@@ -0,0 +1,645 @@
+/*
+ *  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.wrapper.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.UsabilityEvent;
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.applib.events.VisibilityEvent;
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.services.wrapper.DisabledException;
+import org.apache.isis.applib.services.wrapper.HiddenException;
+import org.apache.isis.applib.services.wrapper.InteractionException;
+import org.apache.isis.applib.services.wrapper.InvalidException;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
+import org.apache.isis.core.metamodel.consent.InteractionResult;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.accessor.PropertyOrCollectionAccessorFacet;
+import org.apache.isis.core.metamodel.facets.actions.choices.ActionChoicesFacet;
+import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertyInitializationFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
+import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
+import org.apache.isis.core.progmodel.facets.actions.validate.method.ActionValidationFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateRemoveFromFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.members.disabled.method.DisableForContextFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.members.hidden.method.HideForContextFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.properties.modify.PropertyClearFacetViaClearMethod;
+import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaModifyMethod;
+import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacetViaMethod;
+
+public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandlerDefault<T> {
+
+    private final Map<Method, Collection<?>> collectionViewObjectsByMethod = new HashMap<Method, Collection<?>>();
+    private final Map<Method, Map<?, ?>> mapViewObjectsByMethod = new HashMap<Method, Map<?, ?>>();
+
+    private final AuthenticationSessionProvider authenticationSessionProvider;
+    private final SpecificationLoader specificationLookup;
+    private final AdapterManager adapterManager;
+    private final ObjectPersistor objectPersistor;
+
+    /**
+     * The <tt>title()</tt> method; may be <tt>null</tt>.
+     */
+    protected Method titleMethod;
+
+    /**
+     * The <tt>save()</tt> method from {@link WrapperObject#save()}.
+     */
+    protected Method saveMethod;
+
+    /**
+     * The <tt>underlying()</tt> method from {@link WrapperObject#wrapped()}.
+     */
+    protected Method wrappedMethod;
+
+    public DomainObjectInvocationHandler(final T delegate, final WrapperFactory embeddedViewer, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager,
+            final ObjectPersistor objectPersistor) {
+        super(delegate, embeddedViewer, mode);
+
+        this.authenticationSessionProvider = authenticationSessionProvider;
+        this.specificationLookup = specificationLookup;
+        this.adapterManager = adapterManager;
+        this.objectPersistor = objectPersistor;
+
+        try {
+            titleMethod = delegate.getClass().getMethod("title", new Class[] {});
+            saveMethod = WrapperObject.class.getMethod("save", new Class[] {});
+            wrappedMethod = WrapperObject.class.getMethod("wrapped", new Class[] {});
+        } catch (final NoSuchMethodException e) {
+        }
+    }
+
+    @Override
+    public Object invoke(final Object proxyObject, final Method method, final Object[] args) throws Throwable {
+
+        if (isObjectMethod(method)) {
+            return delegate(method, args);
+        }
+
+        final ObjectAdapter targetAdapter = getAdapterManager().getAdapterFor(getDelegate());
+
+        if (isTitleMethod(method)) {
+            return handleTitleMethod(method, args, targetAdapter);
+        }
+
+        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
+
+        // save method, through the proxy
+        if (isSaveMethod(method)) {
+            return handleSaveMethod(getAuthenticationSession(), targetAdapter, targetNoSpec);
+        }
+
+        if (isUnderlyingMethod(method)) {
+            return getDelegate();
+        }
+
+        final ObjectMember objectMember = locateAndCheckMember(method);
+        final List<Facet> imperativeFacets = getImperativeFacets(objectMember, method);
+
+        final String memberName = objectMember.getName();
+
+        if (instanceOf(imperativeFacets, DisableForContextFacetViaMethod.class, HideForContextFacetViaMethod.class)) {
+            throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'", memberName));
+        }
+
+        final String methodName = method.getName();
+
+        if (instanceOf(imperativeFacets, ActionDefaultsFacet.class, PropertyDefaultFacet.class, ActionChoicesFacet.class, ActionParameterChoicesFacet.class, PropertyChoicesFacet.class)) {
+            return method.invoke(getDelegate(), args);
+        }
+
+        // for all members, check visibility and usability
+        checkVisibility(getAuthenticationSession(), targetAdapter, objectMember);
+
+        if (objectMember.isOneToOneAssociation()) {
+
+            if (instanceOf(imperativeFacets, PropertyValidateFacetViaMethod.class, PropertySetterFacetViaModifyMethod.class, PropertyClearFacetViaClearMethod.class)) {
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only property accessor/mutator", memberName));
+            }
+
+            final OneToOneAssociation otoa = (OneToOneAssociation) objectMember;
+            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
+                return handleGetterMethodOnProperty(args, targetAdapter, otoa, methodName);
+            }
+            if (instanceOf(imperativeFacets, PropertySetterFacet.class, PropertyInitializationFacet.class)) {
+                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+                return handleSetterMethodOnProperty(args, getAuthenticationSession(), targetAdapter, otoa, methodName);
+            }
+        }
+        if (objectMember.isOneToManyAssociation()) {
+
+            if (instanceOf(imperativeFacets, CollectionValidateAddToFacetViaMethod.class, CollectionValidateRemoveFromFacetViaMethod.class)) {
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only collection accessor/mutator", memberName));
+            }
+
+            final OneToManyAssociation otma = (OneToManyAssociation) objectMember;
+            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
+                return handleGetterMethodOnCollection(method, args, targetAdapter, otma, memberName);
+            }
+            if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
+                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+                return handleCollectionAddToMethod(args, targetAdapter, otma, methodName);
+            }
+            if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
+                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+                return handleCollectionRemoveFromMethod(args, targetAdapter, otma, methodName);
+            }
+        }
+
+        // filter out
+        if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke accessor on properties or collections; '%s' represents %s", methodName, decode(objectMember)));
+        }
+        if (instanceOf(imperativeFacets, PropertySetterFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke mutator on properties; '%s' represents %s", methodName, decode(objectMember)));
+        }
+        if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke 'adder' on collections; '%s' represents %s", methodName, decode(objectMember)));
+        }
+        if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke 'remover' on collections; '%s' represents %s", methodName, decode(objectMember)));
+        }
+
+        if (objectMember instanceof ObjectAction) {
+
+            if (instanceOf(imperativeFacets, ActionValidationFacetViaMethod.class)) {
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only the 'invoke' method", memberName));
+            }
+
+            checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+
+            final ObjectAction noa = (ObjectAction) objectMember;
+            return handleActionMethod(args, getAuthenticationSession(), targetAdapter, noa, memberName);
+        }
+
+        throw new UnsupportedOperationException(String.format("Unknown member type '%s'", objectMember));
+    }
+
+    public List<Facet> getImperativeFacets(final ObjectMember objectMember, final Method method) {
+        final List<Facet> imperativeFacets = objectMember.getFacets(new Filter<Facet>() {
+            @Override
+            public boolean accept(final Facet facet) {
+                final ImperativeFacet imperativeFacet = asImperativeFacet(facet);
+                if (imperativeFacet == null) {
+                    return false;
+                }
+                return imperativeFacet.getMethods().contains(method);
+            }
+
+            private ImperativeFacet asImperativeFacet(final Facet facet) {
+                if (facet == null) {
+                    return null;
+                }
+                if (facet instanceof ImperativeFacet) {
+                    return (ImperativeFacet) facet;
+                }
+                return asImperativeFacet(facet.getUnderlyingFacet());
+            }
+        });
+
+        // there will be at least one
+        if (imperativeFacets.isEmpty()) {
+            throw new IllegalStateException("should be at least one imperative facet");
+        }
+        return imperativeFacets;
+    }
+
+    private static boolean instanceOf(final List<?> objects, final Class<?>... superTypes) {
+        for (final Class<?> superType : superTypes) {
+            for (final Object obj : objects) {
+                if (superType.isAssignableFrom(obj.getClass())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // title
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleTitleMethod(final Method method, final Object[] args, final ObjectAdapter targetAdapter) throws IllegalAccessException, InvocationTargetException {
+
+        resolveIfRequired(targetAdapter);
+
+        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
+        final ObjectTitleContext titleContext = targetNoSpec.createTitleInteractionContext(getAuthenticationSession(), InteractionInvocationMethod.BY_USER, targetAdapter);
+        final ObjectTitleEvent titleEvent = titleContext.createInteractionEvent();
+        notifyListeners(titleEvent);
+        return titleEvent.getTitle();
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // save
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleSaveMethod(final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectSpecification targetNoSpec) {
+
+        final InteractionResult interactionResult = targetNoSpec.isValidResult(targetAdapter);
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            if (targetAdapter.isTransient()) {
+                getObjectPersistor().makePersistent(targetAdapter);
+            }
+        }
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // property - access
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleGetterMethodOnProperty(final Object[] args, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
+        if (args.length != 0) {
+            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final ObjectAdapter currentReferencedAdapter = otoa.get(targetAdapter);
+        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
+
+        final PropertyAccessEvent ev = new PropertyAccessEvent(getDelegate(), otoa.getIdentifier(), currentReferencedObj);
+        notifyListeners(ev);
+        return currentReferencedObj;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // property - modify
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleSetterMethodOnProperty(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
+        if (args.length != 1) {
+            throw new IllegalArgumentException("Invoking a setter should only have a single argument");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final Object argumentObj = underlying(args[0]);
+        final ObjectAdapter argumentAdapter = argumentObj != null ? getAdapterManager().adapterFor(argumentObj) : null;
+
+        final InteractionResult interactionResult = otoa.isAssociationValid(targetAdapter, argumentAdapter).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            otoa.set(targetAdapter, argumentAdapter);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // collection - access
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleGetterMethodOnCollection(final Method method, final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String memberName) {
+        if (args.length != 0) {
+            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final ObjectAdapter currentReferencedAdapter = otma.get(targetAdapter);
+        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
+
+        final CollectionAccessEvent ev = new CollectionAccessEvent(getDelegate(), otma.getIdentifier());
+
+        if (currentReferencedObj instanceof Collection) {
+            final Collection<?> collectionViewObject = lookupViewObject(method, memberName, (Collection<?>) currentReferencedObj, otma);
+            notifyListeners(ev);
+            return collectionViewObject;
+        } else if (currentReferencedObj instanceof Map) {
+            final Map<?, ?> mapViewObject = lookupViewObject(method, memberName, (Map<?, ?>) currentReferencedObj, otma);
+            notifyListeners(ev);
+            return mapViewObject;
+        }
+        throw new IllegalArgumentException(String.format("Collection type '%s' not supported by framework", currentReferencedObj.getClass().getName()));
+    }
+
+    /**
+     * Looks up (or creates) a proxy for this object.
+     */
+    private Collection<?> lookupViewObject(final Method method, final String memberName, final Collection<?> collectionToLookup, final OneToManyAssociation otma) {
+        Collection<?> collectionViewObject = collectionViewObjectsByMethod.get(method);
+        if (collectionViewObject == null) {
+            if (collectionToLookup instanceof WrapperObject) {
+                collectionViewObject = collectionToLookup;
+            } else {
+                collectionViewObject = Proxy.proxy(collectionToLookup, memberName, this, otma);
+            }
+            collectionViewObjectsByMethod.put(method, collectionViewObject);
+        }
+        return collectionViewObject;
+    }
+
+    private Map<?, ?> lookupViewObject(final Method method, final String memberName, final Map<?, ?> mapToLookup, final OneToManyAssociation otma) {
+        Map<?, ?> mapViewObject = mapViewObjectsByMethod.get(method);
+        if (mapViewObject == null) {
+            if (mapToLookup instanceof WrapperObject) {
+                mapViewObject = mapToLookup;
+            } else {
+                mapViewObject = Proxy.proxy(mapToLookup, memberName, this, otma);
+            }
+            mapViewObjectsByMethod.put(method, mapViewObject);
+        }
+        return mapViewObject;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // collection - add to
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleCollectionAddToMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
+
+        if (args.length != 1) {
+            throw new IllegalArgumentException("Invoking a addTo should only have a single argument");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final Object argumentObj = underlying(args[0]);
+        if (argumentObj == null) {
+            throw new IllegalArgumentException("Must provide a non-null object to add");
+        }
+        final ObjectAdapter argumentNO = getAdapterManager().adapterFor(argumentObj);
+
+        final InteractionResult interactionResult = otma.isValidToAdd(targetAdapter, argumentNO).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            otma.addElement(targetAdapter, argumentNO);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // collection - remove from
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleCollectionRemoveFromMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
+        if (args.length != 1) {
+            throw new IllegalArgumentException("Invoking a removeFrom should only have a single argument");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final Object argumentObj = underlying(args[0]);
+        if (argumentObj == null) {
+            throw new IllegalArgumentException("Must provide a non-null object to remove");
+        }
+        final ObjectAdapter argumentAdapter = getAdapterManager().adapterFor(argumentObj);
+
+        final InteractionResult interactionResult = otma.isValidToRemove(targetAdapter, argumentAdapter).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            otma.removeElement(targetAdapter, argumentAdapter);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // action
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleActionMethod(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectAction noa, final String memberName) {
+
+        final Object[] underlyingArgs = new Object[args.length];
+        int i = 0;
+        for (final Object arg : args) {
+            underlyingArgs[i++] = underlying(arg);
+        }
+
+        final ObjectAdapter[] argAdapters = new ObjectAdapter[underlyingArgs.length];
+        int j = 0;
+        for (final Object underlyingArg : underlyingArgs) {
+            argAdapters[j++] = underlyingArg != null ? getAdapterManager().adapterFor(underlyingArg) : null;
+        }
+
+        final InteractionResult interactionResult = noa.isProposedArgumentSetValid(targetAdapter, argAdapters).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            final ObjectAdapter actionReturnNO = noa.execute(targetAdapter, argAdapters);
+            return AdapterUtils.unwrap(actionReturnNO);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    private Object underlying(final Object arg) {
+        if (arg instanceof WrapperObject) {
+            final WrapperObject argViewObject = (WrapperObject) arg;
+            return argViewObject.wrapped();
+        } else {
+            return arg;
+        }
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // visibility and usability checks (common to all members)
+    // /////////////////////////////////////////////////////////////////
+
+    /**
+     * REVIEW: ideally should provide some way to allow to caller to indicate the 'where' context.  Having
+     * a hard-coded value like this is an approximation. 
+     */
+    private final Where where = Where.ANYWHERE;
+
+    private void checkVisibility(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
+        final Consent visibleConsent = objectMember.isVisible(getAuthenticationSession(), targetObjectAdapter, where);
+        final InteractionResult interactionResult = visibleConsent.getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+    }
+
+    private void checkUsability(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
+        final InteractionResult interactionResult = objectMember.isUsable(getAuthenticationSession(), targetObjectAdapter, where).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // notify listeners
+    // /////////////////////////////////////////////////////////////////
+
+    private void notifyListenersAndVetoIfRequired(final InteractionResult interactionResult) {
+        final InteractionEvent interactionEvent = interactionResult.getInteractionEvent();
+        notifyListeners(interactionEvent);
+        if (interactionEvent.isVeto()) {
+            throw toException(interactionEvent);
+        }
+    }
+
+    private String decode(final ObjectMember objectMember) {
+        if (objectMember instanceof OneToOneAssociation) {
+            return "a property";
+        }
+        if (objectMember instanceof OneToManyAssociation) {
+            return "a collection";
+        }
+        if (objectMember instanceof ObjectAction) {
+            return "an action";
+        }
+        return "an UNKNOWN member type";
+    }
+
+    /**
+     * Wraps a {@link InteractionEvent#isVeto() vetoing}
+     * {@link InteractionEvent} in a corresponding {@link InteractionException},
+     * and returns it.
+     */
+    private InteractionException toException(final InteractionEvent interactionEvent) {
+        if (!interactionEvent.isVeto()) {
+            throw new IllegalArgumentException("Provided interactionEvent must be a veto");
+        }
+        if (interactionEvent instanceof ValidityEvent) {
+            final ValidityEvent validityEvent = (ValidityEvent) interactionEvent;
+            return new InvalidException(validityEvent);
+        }
+        if (interactionEvent instanceof VisibilityEvent) {
+            final VisibilityEvent visibilityEvent = (VisibilityEvent) interactionEvent;
+            return new HiddenException(visibilityEvent);
+        }
+        if (interactionEvent instanceof UsabilityEvent) {
+            final UsabilityEvent usabilityEvent = (UsabilityEvent) interactionEvent;
+            return new DisabledException(usabilityEvent);
+        }
+        throw new IllegalArgumentException("Provided interactionEvent must be a VisibilityEvent, UsabilityEvent or a ValidityEvent");
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // switching
+    // /////////////////////////////////////////////////////////////////
+
+    private ObjectMember locateAndCheckMember(final Method method) {
+        final ObjectSpecificationDefault objectSpecificationDefault = getJavaSpecificationOfOwningClass(method);
+        final ObjectMember member = objectSpecificationDefault.getMember(method);
+        if (member == null) {
+            final String methodName = method.getName();
+            throw new UnsupportedOperationException("Method '" + methodName + "' being invoked does not correspond to any of the object's fields or actions.");
+        }
+        return member;
+    }
+
+    protected boolean isTitleMethod(final Method method) {
+        return method.equals(titleMethod);
+    }
+
+    protected boolean isSaveMethod(final Method method) {
+        return method.equals(saveMethod);
+    }
+
+    protected boolean isUnderlyingMethod(final Method method) {
+        return method.equals(wrappedMethod);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Specification lookup
+    // /////////////////////////////////////////////////////////////////
+
+    private ObjectSpecificationDefault getJavaSpecificationOfOwningClass(final Method method) {
+        return getJavaSpecification(method.getDeclaringClass());
+    }
+
+    private ObjectSpecificationDefault getJavaSpecification(final Class<?> clazz) {
+        final ObjectSpecification nos = getSpecification(clazz);
+        if (!(nos instanceof ObjectSpecificationDefault)) {
+            throw new UnsupportedOperationException("Only Java is supported (specification is '" + nos.getClass().getCanonicalName() + "')");
+        }
+        return (ObjectSpecificationDefault) nos;
+    }
+
+    private ObjectSpecification getSpecification(final Class<?> type) {
+        final ObjectSpecification nos = getSpecificationLookup().loadSpecification(type);
+        return nos;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Dependencies
+    // /////////////////////////////////////////////////////////////////
+
+    protected SpecificationLoader getSpecificationLookup() {
+        return specificationLookup;
+    }
+
+    public AuthenticationSessionProvider getAuthenticationSessionProvider() {
+        return authenticationSessionProvider;
+    }
+
+    protected AuthenticationSession getAuthenticationSession() {
+        return getAuthenticationSessionProvider().getAuthenticationSession();
+    }
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+    protected ObjectPersistor getObjectPersistor() {
+        return objectPersistor;
+    }
+
+}


[3/8] ISIS-409: moving wrapper progmodel into core, as a service

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java b/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
deleted file mode 100644
index 12c3c99..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-
-import org.apache.isis.core.tck.dom.claimapp.employees.Employee;
-import org.apache.isis.core.tck.dom.claimapp.employees.EmployeeRepository;
-import org.apache.isis.core.tck.dom.claimapp.employees.EmployeeRepositoryImpl;
-import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
-import org.apache.isis.progmodel.wrapper.applib.HiddenException;
-import org.apache.isis.progmodel.wrapper.applib.InvalidException;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
-
-public class WrappedFactoryDefaultTest_wrappedObject {
-
-    @Rule
-    public JUnitRuleMockery2 mockery = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY);
-
-    private EmployeeRepository employeeRepository;
-    // private ClaimRepository claimRepository;
-
-    private Employee employeeDO;
-    private Employee employeeWO;
-
-    private WrapperFactory wrapperFactory;
-
-    @Before
-    public void setUp() {
-
-        employeeRepository = new EmployeeRepositoryImpl();
-        // claimRepository = new ClaimRepositoryImpl();
-
-        employeeDO = new Employee();
-        employeeDO.setName("Smith");
-        employeeDO.setEmployeeRepository(employeeRepository); // would be done
-                                                              // by the
-                                                              // EmbeddedContext
-                                                              // impl
-
-        wrapperFactory = new WrapperFactoryDefault();
-        employeeWO = wrapperFactory.wrap(employeeDO);
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test
-    public void shouldWrapDomainObject() {
-        // then
-        assertThat(employeeWO, is(notNullValue()));
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test
-    public void shouldBeAbleToInjectIntoDomainObjects() {
-
-        // given
-        assertThat(employeeDO.getEmployeeRepository(), is(notNullValue()));
-
-        // then
-        assertThat(employeeWO.getEmployeeRepository(), is(notNullValue()));
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test
-    public void shouldBeAbleToReadVisibleProperty() {
-        // then
-        assertThat(employeeWO.getName(), is(employeeDO.getName()));
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test(expected = HiddenException.class)
-    public void shouldNotBeAbleToViewHiddenProperty() {
-        // given
-        employeeDO.whetherHideName = true;
-        // when
-        employeeWO.getName();
-        // then should throw exception
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test
-    public void shouldBeAbleToModifyEnabledPropertyUsingSetter() {
-        // when
-        employeeWO.setName("Jones");
-        // then
-        assertThat(employeeDO.getName(), is("Jones"));
-        assertThat(employeeWO.getName(), is(employeeDO.getName()));
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test(expected = DisabledException.class)
-    public void shouldNotBeAbleToModifyDisabledProperty() {
-        // given
-        employeeDO.reasonDisableName = "sorry, no change allowed";
-        // when
-        employeeWO.setName("Jones");
-        // then should throw exception
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test(expected = UnsupportedOperationException.class)
-    public void shouldNotBeAbleToModifyPropertyUsingModify() {
-        // when
-        employeeWO.modifyName("Jones");
-        // then should throw exception
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test(expected = UnsupportedOperationException.class)
-    public void shouldNotBeAbleToModifyPropertyUsingClear() {
-        // when
-        employeeWO.clearName();
-        // then should throw exception
-    }
-
-    @Ignore("TODO - moved from embedded runtime, need to re-enable")
-    @Test(expected = InvalidException.class)
-    public void shouldNotBeAbleToModifyPropertyIfInvalid() {
-        // given
-        employeeDO.reasonValidateName = "sorry, invalid data";
-        // when
-        employeeWO.setName("Jones");
-        // then should throw exception
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java b/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
deleted file mode 100644
index 34eb6d9..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.jmock.Expectations;
-import org.jmock.auto.Mock;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.events.PropertyModifyEvent;
-import org.apache.isis.applib.events.PropertyUsabilityEvent;
-import org.apache.isis.applib.events.PropertyVisibilityEvent;
-import org.apache.isis.applib.filter.Filter;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.consent.Allow;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionResult;
-import org.apache.isis.core.metamodel.consent.Veto;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
-import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacet;
-import org.apache.isis.core.progmodel.facets.members.disabled.staticmethod.DisabledFacetAlwaysEverywhere;
-import org.apache.isis.core.progmodel.facets.properties.accessor.PropertyAccessorFacetViaAccessor;
-import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaSetterMethod;
-import org.apache.isis.core.runtime.authentication.standard.SimpleSession;
-import org.apache.isis.core.tck.dom.claimapp.employees.Employee;
-import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
-import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
-import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
-
-public class WrappedFactoryDefaultTest_wrappedObject_transient {
-
-    @Rule
-    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-
-    @Mock
-    private AdapterManager mockAdapterManager;
-    @Mock
-    private AuthenticationSessionProvider mockAuthenticationSessionProvider;
-    @Mock
-    private ObjectPersistor mockObjectPersistor;
-    @Mock
-    private SpecificationLoader mockSpecificationLookup;
-
-    private Employee employeeDO;
-    @Mock
-    private ObjectAdapter mockEmployeeAdapter;
-    @Mock
-    private ObjectSpecificationDefault mockEmployeeSpec;
-    @Mock
-    private OneToOneAssociation mockPasswordMember;
-    @Mock
-    private Identifier mockPasswordIdentifier;
-
-    @Mock
-    protected ObjectAdapter mockPasswordAdapter;
-    
-    private final String passwordValue = "12345678";
-
-    private final SimpleSession session = new SimpleSession("tester", Collections.<String>emptyList());
-
-    private List<Facet> facets;
-    private Method getPasswordMethod;
-    private Method setPasswordMethod;
-
-
-    private WrapperFactoryDefault wrapperFactory;
-    private Employee employeeWO;
-
-
-    @Before
-    public void setUp() throws Exception {
-
-        // employeeRepository = new EmployeeRepositoryImpl();
-        // claimRepository = new ClaimRepositoryImpl();
-
-        employeeDO = new Employee();
-        employeeDO.setName("Smith");
-        
-        getPasswordMethod = Employee.class.getMethod("getPassword");
-        setPasswordMethod = Employee.class.getMethod("setPassword", String.class);
-
-        wrapperFactory = new WrapperFactoryDefault();
-        wrapperFactory.setAdapterManager(mockAdapterManager);
-        wrapperFactory.setAuthenticationSessionProvider(mockAuthenticationSessionProvider);
-        wrapperFactory.setObjectPersistor(mockObjectPersistor);
-        wrapperFactory.setSpecificationLookup(mockSpecificationLookup);
-        
-        context.checking(new Expectations() {
-            {
-                allowing(mockAdapterManager).getAdapterFor(employeeDO);
-                will(returnValue(mockEmployeeAdapter));
-
-                allowing(mockAdapterManager).adapterFor(passwordValue);
-                will(returnValue(mockPasswordAdapter));
-
-                allowing(mockEmployeeAdapter).getSpecification();
-                will(returnValue(mockEmployeeSpec));
-
-                allowing(mockEmployeeAdapter).getObject();
-                will(returnValue(employeeDO));
-
-                allowing(mockPasswordAdapter).getObject();
-                will(returnValue(passwordValue));
-
-                allowing(mockPasswordMember).getIdentifier();
-                will(returnValue(mockPasswordIdentifier));
-
-                allowing(mockSpecificationLookup).loadSpecification(Employee.class);
-                will(returnValue(mockEmployeeSpec));
-                
-                allowing(mockEmployeeSpec).getMember(with(setPasswordMethod));
-                will(returnValue(mockPasswordMember));
-
-                allowing(mockEmployeeSpec).getMember(with(getPasswordMethod));
-                will(returnValue(mockPasswordMember));
-
-                allowing(mockPasswordMember).getName();
-                will(returnValue("password"));
-
-                allowing(mockAuthenticationSessionProvider).getAuthenticationSession();
-                will(returnValue(session));
-                
-                allowing(mockPasswordMember).isOneToOneAssociation();
-                will(returnValue(true));
-
-                allowing(mockPasswordMember).isOneToManyAssociation();
-                will(returnValue(false));
-            }
-        });
-
-        employeeWO = wrapperFactory.wrap(employeeDO);
-    }
-
-    @Test(expected = DisabledException.class)
-    public void shouldNotBeAbleToModifyProperty() {
-
-        // given
-        final DisabledFacet disabledFacet = new DisabledFacetAlwaysEverywhere(mockPasswordMember);
-        facets = Arrays.asList((Facet)disabledFacet, new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
-
-        final Consent visibilityConsent = new Allow(new InteractionResult(new PropertyVisibilityEvent(employeeDO, null)));
-
-        final InteractionResult usabilityInteractionResult = new InteractionResult(new PropertyUsabilityEvent(employeeDO, null));
-        usabilityInteractionResult.advise("disabled", disabledFacet);
-        final Consent usabilityConsent = new Veto(usabilityInteractionResult);
-
-        context.checking(new Expectations() {
-            {
-                allowing(mockPasswordMember).getFacets(with(any(Filter.class)));
-                will(returnValue(facets));
-                
-                allowing(mockPasswordMember).isVisible(session, mockEmployeeAdapter, Where.ANYWHERE);
-                will(returnValue(visibilityConsent));
-                
-                allowing(mockPasswordMember).isUsable(session, mockEmployeeAdapter, Where.ANYWHERE);
-                will(returnValue(usabilityConsent));
-            }
-        });
-        
-        // when
-        employeeWO.setPassword(passwordValue);
-        
-        // then should throw exception
-    }
-
-    @Test
-    public void canModifyProperty() {
-        // given
-
-        final Consent visibilityConsent = new Allow(new InteractionResult(new PropertyVisibilityEvent(employeeDO, mockPasswordIdentifier)));
-        final Consent usabilityConsent = new Allow(new InteractionResult(new PropertyUsabilityEvent(employeeDO, mockPasswordIdentifier)));
-        final Consent validityConsent = new Allow(new InteractionResult(new PropertyModifyEvent(employeeDO, mockPasswordIdentifier, passwordValue)));
-
-        context.checking(new Expectations() {
-            {
-                allowing(mockPasswordMember).isVisible(session, mockEmployeeAdapter, Where.ANYWHERE);
-                will(returnValue(visibilityConsent));
-                
-                allowing(mockPasswordMember).isUsable(session, mockEmployeeAdapter, Where.ANYWHERE);
-                will(returnValue(usabilityConsent));
-                
-                allowing(mockPasswordMember).isAssociationValid(mockEmployeeAdapter, mockPasswordAdapter);
-                will(returnValue(validityConsent));
-            }
-        });
-
-        facets = Arrays.asList((Facet)new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
-        context.checking(new Expectations() {
-            {
-                one(mockPasswordMember).getFacets(with(any(Filter.class)));
-                will(returnValue(facets));
-                
-                one(mockPasswordMember).set(mockEmployeeAdapter, mockPasswordAdapter);
-            }
-        });
-
-        // when
-        employeeWO.setPassword(passwordValue);
-
-
-        // and given
-        facets = Arrays.asList((Facet)new PropertyAccessorFacetViaAccessor(getPasswordMethod, mockPasswordMember));
-        context.checking(new Expectations() {
-            {
-                one(mockPasswordMember).getFacets(with(any(Filter.class)));
-                will(returnValue(facets));
-                
-                one(mockPasswordMember).get(mockEmployeeAdapter);
-                will(returnValue(mockPasswordAdapter));
-            }
-        });
-
-        // then be allowed
-        assertThat(employeeWO.getPassword(), is(passwordValue));
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/pom.xml
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/pom.xml b/component/viewer/junit/impl/pom.xml
index 09dca4d..cd69bfc 100644
--- a/component/viewer/junit/impl/pom.xml
+++ b/component/viewer/junit/impl/pom.xml
@@ -67,8 +67,8 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.isis.progmodel</groupId>
-            <artifactId>isis-progmodel-wrapper-metamodel</artifactId>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-wrapper</artifactId>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
index 3c1c625..bf87851 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/AbstractTest.java
@@ -24,7 +24,7 @@ import org.junit.Before;
 import org.junit.runner.RunWith;
 
 import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.viewer.junit.sample.domain.Country;
 import org.apache.isis.viewer.junit.sample.domain.Customer;
 import org.apache.isis.viewer.junit.sample.domain.Product;

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/InteractionListenerTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/InteractionListenerTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/InteractionListenerTest.java
index e33df98..9cb9cd2 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/InteractionListenerTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/InteractionListenerTest.java
@@ -27,8 +27,8 @@ import org.junit.Test;
 
 import org.apache.isis.applib.events.InteractionEvent;
 import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.progmodel.wrapper.applib.listeners.InteractionAdapter;
-import org.apache.isis.progmodel.wrapper.applib.listeners.InteractionListener;
+import org.apache.isis.applib.services.wrapper.listeners.InteractionAdapter;
+import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
 import org.apache.isis.viewer.junit.sample.domain.Customer;
 
 public class InteractionListenerTest extends AbstractTest {

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberDisabledTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberDisabledTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberDisabledTest.java
index 8e5b3a2..0bb145b 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberDisabledTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberDisabledTest.java
@@ -28,9 +28,9 @@ import java.util.List;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.services.wrapper.DisabledException;
 import org.apache.isis.core.progmodel.facets.members.disabled.annotation.DisabledFacetAnnotation;
 import org.apache.isis.core.progmodel.facets.members.disabled.method.DisableForContextFacetViaMethod;
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
 import org.apache.isis.viewer.junit.sample.domain.Order;
 
 public class MemberDisabledTest extends AbstractTest {

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberHiddenTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberHiddenTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberHiddenTest.java
index 6a30fbf..d8cb0c8 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberHiddenTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberHiddenTest.java
@@ -26,10 +26,10 @@ import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.services.wrapper.HiddenException;
 import org.apache.isis.core.progmodel.facets.members.hidden.annotation.HiddenFacetForMemberAnnotation;
 import org.apache.isis.core.progmodel.facets.members.hidden.forsession.HideForSessionFacetViaMethod;
 import org.apache.isis.core.progmodel.facets.members.hidden.method.HideForContextFacetViaMethod;
-import org.apache.isis.progmodel.wrapper.applib.HiddenException;
 import org.apache.isis.viewer.junit.sample.domain.Country;
 
 public class MemberHiddenTest extends AbstractTest {

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberInvalidTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberInvalidTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberInvalidTest.java
index c176bca..3ef955f 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberInvalidTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberInvalidTest.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.services.wrapper.InvalidException;
 import org.apache.isis.core.metamodel.facets.mandatory.MandatoryFacetDefault;
 import org.apache.isis.core.progmodel.facets.actions.validate.method.ActionValidationFacetViaMethod;
 import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
@@ -33,7 +34,6 @@ import org.apache.isis.core.progmodel.facets.collections.validate.CollectionVali
 import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacetViaMethod;
 import org.apache.isis.core.progmodel.facets.properties.validate.maxlenannot.MaxLengthFacetAnnotationForProperty;
 import org.apache.isis.core.progmodel.facets.properties.validate.regexannot.RegExFacetAnnotationForProperty;
-import org.apache.isis.progmodel.wrapper.applib.InvalidException;
 import org.apache.isis.viewer.junit.sample.domain.Country;
 
 public class MemberInvalidTest extends AbstractTest {

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberModifyTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberModifyTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberModifyTest.java
index 12cf26d..0e87673 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberModifyTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/MemberModifyTest.java
@@ -30,7 +30,7 @@ import java.util.List;
 
 import org.junit.Test;
 
-import org.apache.isis.progmodel.wrapper.applib.InvalidException;
+import org.apache.isis.applib.services.wrapper.InvalidException;
 import org.apache.isis.viewer.junit.sample.domain.Country;
 import org.apache.isis.viewer.junit.sample.domain.Order;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ObjectImmutableTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ObjectImmutableTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ObjectImmutableTest.java
index 8bd1e8f..3abcec6 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ObjectImmutableTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ObjectImmutableTest.java
@@ -26,9 +26,9 @@ import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.services.wrapper.DisabledException;
 import org.apache.isis.core.progmodel.facets.collections.disabled.fromimmutable.DisabledFacetForCollectionDerivedFromImmutable;
 import org.apache.isis.core.progmodel.facets.properties.disabled.fromimmutable.DisabledFacetForPropertyDerivedFromImmutable;
-import org.apache.isis.progmodel.wrapper.applib.DisabledException;
 
 public class ObjectImmutableTest extends AbstractTest {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/SaveObjectsTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/SaveObjectsTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/SaveObjectsTest.java
index 994c529..726b051 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/SaveObjectsTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/SaveObjectsTest.java
@@ -27,9 +27,9 @@ import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.services.wrapper.InvalidException;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
 import org.apache.isis.core.progmodel.facets.object.validate.method.ValidateObjectFacetViaValidateMethod;
-import org.apache.isis.progmodel.wrapper.applib.InvalidException;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
 import org.apache.isis.viewer.junit.sample.domain.Customer;
 
 public class SaveObjectsTest extends AbstractTest {

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ViewObjectTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ViewObjectTest.java b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ViewObjectTest.java
index 668bc2a..dcc4593 100644
--- a/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ViewObjectTest.java
+++ b/component/viewer/junit/impl/src/test/java/org/apache/isis/viewer/junit/ViewObjectTest.java
@@ -28,7 +28,7 @@ import java.util.List;
 
 import org.junit.Test;
 
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
 import org.apache.isis.viewer.junit.sample.domain.Country;
 import org.apache.isis.viewer.junit.sample.domain.Customer;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java b/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
index d62b5eb..9924061 100644
--- a/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
+++ b/component/viewer/junit/tck/src/test/java/junit/AbstractTest.java
@@ -24,9 +24,9 @@ import org.junit.Before;
 import org.junit.runner.RunWith;
 
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
 import org.apache.isis.core.tck.dom.scalars.PrimitiveValuedEntityRepository;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
 import org.apache.isis.viewer.junit.ConfigDir;
 import org.apache.isis.viewer.junit.IsisTestRunner;
 import org.apache.isis.viewer.junit.Service;

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/DisabledException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/DisabledException.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/DisabledException.java
new file mode 100644
index 0000000..a6ba6b2
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/DisabledException.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.applib.services.wrapper;
+
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.UsabilityEvent;
+
+/**
+ * Superclass of exceptions which indicate an attempt to interact with a class
+ * member that is disabled.
+ */
+public class DisabledException extends InteractionException {
+
+    private static final long serialVersionUID = 1L;
+
+    public DisabledException(final InteractionEvent interactionEvent) {
+        super(interactionEvent);
+    }
+
+    @Override
+    public UsabilityEvent getInteractionEvent() {
+        return (UsabilityEvent) super.getInteractionEvent();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/HiddenException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/HiddenException.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/HiddenException.java
new file mode 100644
index 0000000..ab95cd7
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/HiddenException.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.applib.services.wrapper;
+
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.VisibilityEvent;
+
+/**
+ * Superclass of exceptions which indicate an attempt to interact with a class
+ * member that is in some way hidden or invisible.
+ */
+public class HiddenException extends InteractionException {
+
+    private static final long serialVersionUID = 1L;
+
+    public HiddenException(final InteractionEvent interactionEvent) {
+        super(interactionEvent);
+    }
+
+    @Override
+    public VisibilityEvent getInteractionEvent() {
+        return (VisibilityEvent) super.getInteractionEvent();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InteractionException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InteractionException.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InteractionException.java
new file mode 100644
index 0000000..f734b3f
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InteractionException.java
@@ -0,0 +1,75 @@
+/*
+ *  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.applib.services.wrapper;
+
+import org.apache.isis.applib.ApplicationException;
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.events.InteractionEvent;
+
+public abstract class InteractionException extends ApplicationException {
+
+    private static final long serialVersionUID = 1L;
+
+    private final InteractionEvent interactionEvent;
+
+    public InteractionException(final InteractionEvent interactionEvent) {
+        super(interactionEvent.getReason());
+        this.interactionEvent = interactionEvent;
+    }
+
+    /**
+     * The {@link InteractionEvent event} passed into the
+     * {@link #InteractionException(InteractionEvent) constructor}.
+     * 
+     * <p>
+     * Not part of the API, but made available so that subclasses can expose as
+     * the appropriate subtype of {@link InteractionEvent}. This would have been
+     * more obvious to see if {@link InteractionException} was generic, but
+     * generic subclasses of {@link Throwable} are (apparently) not allowed.
+     * 
+     * @return
+     */
+    protected InteractionEvent getInteractionEvent() {
+        return interactionEvent;
+    }
+
+    /**
+     * Convenience method that returns the
+     * {@link InteractionEvent#getAdvisorClass() advisor class} of the wrapped
+     * {@link #getInteractionEvent() interaction event}.
+     * 
+     * @return
+     */
+    public Class<?> getAdvisorClass() {
+        return interactionEvent.getAdvisorClass();
+    }
+
+    /**
+     * Convenience method that returns the
+     * {@link InteractionEvent#getIdentifier() identifier} of the wrapped
+     * {@link #getInteractionEvent() interaction event}.
+     * 
+     * @return
+     */
+    public Identifier getIdentifier() {
+        return interactionEvent.getIdentifier();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InvalidException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InvalidException.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InvalidException.java
new file mode 100644
index 0000000..494155c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/InvalidException.java
@@ -0,0 +1,45 @@
+/*
+ *  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.applib.services.wrapper;
+
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.ValidityEvent;
+
+/**
+ * Superclass of exceptions which indicate an attempt to interact with an object
+ * or member in a way that is invalid.
+ * 
+ * <p>
+ * 
+ */
+public class InvalidException extends InteractionException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InvalidException(final InteractionEvent interactionEvent) {
+        super(interactionEvent);
+    }
+
+    @Override
+    public ValidityEvent getInteractionEvent() {
+        return (ValidityEvent) super.getInteractionEvent();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
new file mode 100644
index 0000000..317bbaa
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
@@ -0,0 +1,142 @@
+/*
+ *  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.applib.services.wrapper;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
+
+/**
+ * Provides the ability to &quot;wrap&quot; of a domain object such that it can
+ * be interacted with while enforcing the hide/disable/validate rules implies by
+ * the Isis programming model.
+ * 
+ * <p>
+ * The &quot;wrap&quot; is a CGLib proxy that wraps the underlying domain
+ * object. The wrapper can then be interacted with as follows:
+ * <ul>
+ * <li>a <tt>get</tt> method for properties or collections</li>
+ * <li>a <tt>set</tt> method for properties</li>
+ * <li>an <tt>addTo</tt> or <tt>removeFrom</tt> method for collections</li>
+ * <li>any action</li>
+ * </ul>
+ * 
+ * <p>
+ * Calling any of the above methods may result in a (subclass of)
+ * {@link InteractionException} if the object disallows it. For example, if a
+ * property is annotated with {@link Hidden} then a {@link HiddenException} will
+ * be thrown. Similarly if an action has a <tt>validate</tt> method and the
+ * supplied arguments are invalid then a {@link InvalidException} will be
+ * thrown.
+ * 
+ * <p>
+ * In addition, the following methods may also be called:
+ * <ul>
+ * <li>the <tt>title</tt> method</li>
+ * <li>any <tt>defaultXxx</tt> or <tt>choicesXxx</tt> method</li>
+ * </ul>
+ * 
+ * <p>
+ * An exception will be thrown if any other methods are thrown.
+ */
+public interface WrapperFactory {
+
+    /**
+     * Whether interactions with the wrapper are actually passed onto the
+     * underlying domain object.
+     * 
+     * @see WrapperFactory#wrap(Object, ExecutionMode)
+     */
+    public static enum ExecutionMode {
+        EXECUTE, NO_EXECUTE
+    }
+
+    /**
+     * Provides the &quot;wrapper&quot; of the underlying domain object.
+     * 
+     * <p>
+     * If the object has (see {@link #isWrapper(Object)} already been wrapped),
+     * then should just return the object back unchanged.
+     * 
+     * @see #addInteractionListener(InteractionListener)
+     */
+    <T> T wrap(T domainObject);
+
+    /**
+     * Same as {@link #wrap(Object)}, except the actual execution occurs only if
+     * the <tt>execute</tt> parameter indicates.
+     * 
+     * <p>
+     * Otherwise, will do all the validations (raise exceptions as required
+     * etc.), but doesn't modify the model.
+     */
+    <T> T wrap(T domainObject, ExecutionMode mode);
+
+    /**
+     * Whether the supplied object has been wrapped.
+     * 
+     * @param <T>
+     * @param possibleWrapper
+     *            - object that might or might not be a wrapper.
+     * @return
+     */
+    <T> boolean isWrapper(T possibleWrapper);
+
+    /**
+     * All {@link InteractionListener}s that have been registered using
+     * {@link #addInteractionListener(InteractionListener)}.
+     */
+    List<InteractionListener> getListeners();
+
+    /**
+     * Registers an {@link InteractionListener}, to be notified of interactions
+     * on all wrappers.
+     * 
+     * <p>
+     * This is retrospective: the listener will be notified of interactions even
+     * on wrappers created before the listener was installed. (From an
+     * implementation perspective this is because the wrappers delegate back to
+     * the container to fire the events).
+     * 
+     * @param listener
+     * @return
+     */
+    public boolean addInteractionListener(InteractionListener listener);
+
+    /**
+     * Remove an {@link InteractionListener}, to no longer be notified of
+     * interactions on wrappers.
+     * 
+     * <p>
+     * This is retrospective: the listener will no longer be notified of any
+     * interactions created on any wrappers, not just on those wrappers created
+     * subsequently. (From an implementation perspective this is because the
+     * wrappers delegate back to the container to fire the events).
+     * 
+     * @param listener
+     * @return
+     */
+    public boolean removeInteractionListener(InteractionListener listener);
+
+    public void notifyListeners(InteractionEvent ev);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperObject.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperObject.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperObject.java
new file mode 100644
index 0000000..350446d
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperObject.java
@@ -0,0 +1,49 @@
+/*
+ *  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.applib.services.wrapper;
+
+/**
+ * Implemented by all objects that have been viewed as per
+ * {@link WrapperFactory#wrap(Object)}.
+ */
+public interface WrapperObject {
+
+    /**
+     * Programmatic equivalent of invoking save for a transient object (that is,
+     * like hitting the <i>save</i> button that the DnD viewer automatically
+     * renders.
+     */
+    void save();
+
+    /**
+     * Provide access to the underlying, wrapped object.
+     * 
+     * <p>
+     * Used to unwrap objects used as arguments to actions (otherwise, end up
+     * creating a <tt>ObjectSpecification</tt> for the CGLib-enhanced class, not
+     * the original class).
+     * 
+     * <p>
+     * <b>NOTE: there is a string-literal reference to this name
+     * <tt>DomainObjectInvocationHandler</tt>, so it should not be changed.</b>.
+     */
+    Object wrapped();
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionAdapter.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionAdapter.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionAdapter.java
new file mode 100644
index 0000000..f43a129
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionAdapter.java
@@ -0,0 +1,109 @@
+/*
+ *  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.applib.services.wrapper.listeners;
+
+import org.apache.isis.applib.events.ActionArgumentEvent;
+import org.apache.isis.applib.events.ActionInvocationEvent;
+import org.apache.isis.applib.events.ActionUsabilityEvent;
+import org.apache.isis.applib.events.ActionVisibilityEvent;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.CollectionAddToEvent;
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.CollectionRemoveFromEvent;
+import org.apache.isis.applib.events.CollectionUsabilityEvent;
+import org.apache.isis.applib.events.CollectionVisibilityEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.ObjectValidityEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+
+/**
+ * Provides no-op implementations of each of the methods within
+ * {@link InteractionListener}, to simplify the creation of new listeners.
+ */
+public class InteractionAdapter implements InteractionListener {
+
+    @Override
+    public void propertyVisible(final PropertyVisibilityEvent ev) {
+    }
+
+    @Override
+    public void propertyUsable(final PropertyUsabilityEvent ev) {
+    }
+
+    @Override
+    public void propertyAccessed(final PropertyAccessEvent ev) {
+    }
+
+    @Override
+    public void propertyModified(final PropertyModifyEvent ev) {
+    }
+
+    @Override
+    public void collectionVisible(final CollectionVisibilityEvent ev) {
+    }
+
+    @Override
+    public void collectionUsable(final CollectionUsabilityEvent ev) {
+    }
+
+    @Override
+    public void collectionAccessed(final CollectionAccessEvent ev) {
+    }
+
+    @Override
+    public void collectionAddedTo(final CollectionAddToEvent ev) {
+    }
+
+    @Override
+    public void collectionRemovedFrom(final CollectionRemoveFromEvent ev) {
+    }
+
+    @Override
+    public void collectionMethodInvoked(final CollectionMethodEvent interactionEvent) {
+    }
+
+    @Override
+    public void actionVisible(final ActionVisibilityEvent interactionEvent) {
+    }
+
+    @Override
+    public void actionUsable(final ActionUsabilityEvent ev) {
+    }
+
+    @Override
+    public void actionArgument(final ActionArgumentEvent ev) {
+    }
+
+    @Override
+    public void actionInvoked(final ActionInvocationEvent ev) {
+    }
+
+    @Override
+    public void objectPersisted(final ObjectValidityEvent ev) {
+    }
+
+    @Override
+    public void objectTitleRead(final ObjectTitleEvent ev) {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionListener.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionListener.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionListener.java
new file mode 100644
index 0000000..10c8c36
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/listeners/InteractionListener.java
@@ -0,0 +1,194 @@
+/*
+ *  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.applib.services.wrapper.listeners;
+
+import org.apache.isis.applib.events.ActionArgumentEvent;
+import org.apache.isis.applib.events.ActionInvocationEvent;
+import org.apache.isis.applib.events.ActionUsabilityEvent;
+import org.apache.isis.applib.events.ActionVisibilityEvent;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.CollectionAddToEvent;
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.CollectionRemoveFromEvent;
+import org.apache.isis.applib.events.CollectionUsabilityEvent;
+import org.apache.isis.applib.events.CollectionVisibilityEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.ObjectValidityEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+
+public interface InteractionListener {
+
+    /**
+     * The title was read.
+     * 
+     * @param ev
+     */
+    void objectTitleRead(ObjectTitleEvent ev);
+
+    /**
+     * The object was persisted (or an attempt to persist it was made).
+     * 
+     * @param ev
+     */
+    void objectPersisted(ObjectValidityEvent ev);
+
+    /**
+     * A check was made to determine if a property was visible.
+     * 
+     * @param ev
+     */
+    void propertyVisible(PropertyVisibilityEvent ev);
+
+    /**
+     * A check was made to determine if a property was usable.
+     * 
+     * @param ev
+     */
+    void propertyUsable(PropertyUsabilityEvent ev);
+
+    /**
+     * A property was read.
+     * 
+     * <p>
+     * Unlike most other events, a {@link PropertyAccessEvent} will never have
+     * been vetoed (that is, {@link PropertyAccessEvent#isVeto()} will always be
+     * <tt>false</tt>).
+     * 
+     * @param ev
+     */
+    void propertyAccessed(PropertyAccessEvent ev);
+
+    /**
+     * A property was modified (or an attempt to modify it was made)
+     * 
+     * <p>
+     * Use {@link PropertyModifyEvent#getProposed()} to determine whether the
+     * property was being set or cleared.
+     * 
+     * @param ev
+     */
+    void propertyModified(PropertyModifyEvent ev);
+
+    /**
+     * A check was made to determine if a collection was visible.
+     * 
+     * <p>
+     * Will be fired prior to
+     * {@link #collectionUsable(CollectionUsabilityEvent)}.
+     * 
+     * @param ev
+     */
+    void collectionVisible(CollectionVisibilityEvent ev);
+
+    /**
+     * A check was made to determine if a collection was usable.
+     * 
+     * <p>
+     * Will be fired prior to either
+     * {@link #collectionAccessed(CollectionAccessEvent)} or
+     * {@link #collectionAddedTo(CollectionAddToEvent)} or
+     * {@link #collectionRemovedFrom(CollectionRemoveFromEvent)}.
+     * 
+     * @param ev
+     */
+    void collectionUsable(CollectionUsabilityEvent ev);
+
+    /**
+     * A collection was read.
+     * 
+     * <p>
+     * Unlike most other events, a {@link CollectionAccessEvent} will never have
+     * been vetoed (that is, {@link CollectionAccessEvent#isVeto()} will always
+     * be <tt>false</tt>).
+     * 
+     * @param ev
+     */
+    void collectionAccessed(CollectionAccessEvent ev);
+
+    /**
+     * An object was added to the collection (or an attempt to add it was made).
+     * 
+     * @param ev
+     */
+    void collectionAddedTo(CollectionAddToEvent ev);
+
+    /**
+     * An object was removed from the collection (or an attempt to remove it was
+     * made).
+     * 
+     * @param ev
+     */
+    void collectionRemovedFrom(CollectionRemoveFromEvent ev);
+
+/**
+     * A method of a collection (such as <tt>isEmpty()</tt> or <tt>size()</tt>) has been invoked.
+     * 
+     * 
+     * <p>
+     * Unlike the other methods in this interface, the source of these events will be an instance of a
+     * Collection (such as <tt>java.util.List</tt>) rather than the domain object. (The domain object is
+     * {@link CollectionMethodEvent#getDomainObject() still available,  however).
+     * 
+     * @param interactionEvent
+     */
+    void collectionMethodInvoked(CollectionMethodEvent interactionEvent);
+
+    /**
+     * A check was made to determine if an action was visible.
+     * 
+     * <p>
+     * Will be fired prior to {@link #actionUsable(ActionUsabilityEvent)}.
+     * 
+     * @param ev
+     */
+    void actionVisible(ActionVisibilityEvent interactionEvent);
+
+    /**
+     * A check was made to determine if an action was usable.
+     * 
+     * <p>
+     * Will be fired prior to {@link #actionArgument(ActionArgumentEvent)}.
+     * 
+     * @param ev
+     */
+    void actionUsable(ActionUsabilityEvent ev);
+
+    /**
+     * A check was made as to whether an argument proposed for an action was
+     * valid.
+     * 
+     * <p>
+     * Will be fired prior to {@link #actionInvoked(ActionInvocationEvent)}.
+     * 
+     * @param ev
+     */
+    void actionArgument(ActionArgumentEvent ev);
+
+    /**
+     * An action was invoked (or an attempt to invoke it was made).
+     * 
+     * @param ev
+     */
+    void actionInvoked(ActionInvocationEvent ev);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 4fd7a7a..78e674c 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1055,7 +1055,7 @@ ${license.additional-notes}
                 <version>1.2.0-SNAPSHOT</version>
             </dependency>
 
-            <!-- isis-webserver -->
+            <!-- webserver -->
             <dependency>
                 <groupId>org.apache.isis.core</groupId>
                 <artifactId>isis-core-webserver</artifactId>
@@ -1070,6 +1070,14 @@ ${license.additional-notes}
                 <!-- not scope=test, because referenced by some sql-tests-common under compile scope -->
             </dependency>
 
+            <!-- wrapper service -->
+            <dependency>
+                <groupId>org.apache.isis.core</groupId>
+                <artifactId>isis-core-wrapper</artifactId>
+                <version>1.2.0-SNAPSHOT</version>
+            </dependency>
+
+
             <!-- default implementations of components -->
             <dependency>
                 <groupId>org.apache.isis.core</groupId>
@@ -1790,6 +1798,8 @@ ${license.additional-notes}
         <module>unittestsupport</module>
         <module>integtestsupport</module>
 
+        <module>wrapper</module>
+
         <module>tck</module>
     </modules>
 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/pom.xml
----------------------------------------------------------------------
diff --git a/core/wrapper/pom.xml b/core/wrapper/pom.xml
new file mode 100644
index 0000000..7627a02
--- /dev/null
+++ b/core/wrapper/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.isis.core</groupId>
+        <artifactId>isis</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>isis-core-wrapper</artifactId>
+
+	<name>Isis Core Wrapper Service</name>
+	<description>Isis Core Wrapper Service</description>
+
+
+	<properties>
+        <siteBaseDir>..</siteBaseDir>
+		<relativeUrl>wrapper/</relativeUrl>
+	</properties>
+
+    <!-- used in Site generation for relative references. -->
+    <url>http://isis.apache.org/${relativeUrl}</url>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+				<version>${maven-project-info-reports-plugin}</version>
+                <inherited>false</inherited>
+                <configuration>
+                	<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                </configuration>
+                <reportSets>
+                    <reportSet>
+                        <inherited>false</inherited>
+                        <reports>
+                            <report>dependencies</report>
+                            <report>dependency-convergence</report>
+                            <report>plugins</report>
+                            <report>summary</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+
+	<dependencies>
+        <dependency>
+		    <groupId>org.apache.isis.core</groupId>
+		    <artifactId>isis-core-runtime</artifactId>
+        </dependency>
+
+		<dependency>
+		    <groupId>org.apache.isis.core</groupId>
+		    <artifactId>isis-core-metamodel</artifactId>
+		    <type>test-jar</type>
+		    <scope>test</scope>
+        </dependency>
+		<dependency>
+		    <groupId>org.apache.isis.core</groupId>
+		    <artifactId>isis-core-runtime</artifactId>
+		    <type>test-jar</type>
+		    <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-unittestsupport</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-tck-dom</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+		<dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.objenesis</groupId>
+			<artifactId>objenesis</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>cglib</groupId>
+			<artifactId>cglib-nodep</artifactId>
+		</dependency>
+
+	</dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
new file mode 100644
index 0000000..6b908c8
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
@@ -0,0 +1,116 @@
+/*
+ *  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.progmodel.wrapper.metamodel;
+
+import java.util.List;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+
+/**
+ * A combined {@link DomainObjectContainer} and {@link WrapperFactory}.
+ */
+public class DomainObjectContainerWrapperFactory extends DomainObjectContainerDefault implements WrapperFactory {
+
+    private final WrapperFactoryDefault wrapperFactoryDelegate;
+
+    public DomainObjectContainerWrapperFactory() {
+        this.wrapperFactoryDelegate = new WrapperFactoryDefault();
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Views
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public <T> T wrap(final T domainObject) {
+        return wrapperFactoryDelegate.wrap(domainObject);
+    }
+
+    @Override
+    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
+        return wrapperFactoryDelegate.wrap(domainObject, mode);
+    }
+
+    @Override
+    public boolean isWrapper(final Object possibleView) {
+        return wrapperFactoryDelegate.isWrapper(possibleView);
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public List<InteractionListener> getListeners() {
+        return wrapperFactoryDelegate.getListeners();
+    }
+
+    @Override
+    public boolean addInteractionListener(final InteractionListener listener) {
+        return wrapperFactoryDelegate.addInteractionListener(listener);
+    }
+
+    @Override
+    public boolean removeInteractionListener(final InteractionListener listener) {
+        return wrapperFactoryDelegate.removeInteractionListener(listener);
+    }
+
+    @Override
+    public void notifyListeners(final InteractionEvent interactionEvent) {
+        wrapperFactoryDelegate.notifyListeners(interactionEvent);
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Dependencies
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
+        super.setSpecificationLookup(specificationLookup);
+        wrapperFactoryDelegate.setSpecificationLookup(specificationLookup);
+    }
+
+    @Override
+    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
+        super.setAuthenticationSessionProvider(authenticationSessionProvider);
+        wrapperFactoryDelegate.setAuthenticationSessionProvider(authenticationSessionProvider);
+    }
+
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        super.setAdapterManager(adapterManager);
+        wrapperFactoryDelegate.setAdapterManager(adapterManager);
+    }
+
+    @Override
+    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
+        super.setObjectPersistor(objectPersistor);
+        wrapperFactoryDelegate.setObjectPersistor(objectPersistor);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
new file mode 100644
index 0000000..75e5fce
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
@@ -0,0 +1,89 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+abstract class AbstractCollectionInvocationHandler<T, C> extends DelegatingInvocationHandlerDefault<C> {
+
+    private final List<Method> interceptedMethods = new ArrayList<Method>();
+    private final List<Method> vetoedMethods = new ArrayList<Method>();
+    private final String collectionName;
+    private final OneToManyAssociation oneToManyAssociation;
+    private final T domainObject;
+
+    public AbstractCollectionInvocationHandler(final C collectionOrMapToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionOrMapToProxy, handler.getHeadlessViewer(), handler.getExecutionMode());
+        this.collectionName = collectionName;
+        this.oneToManyAssociation = otma;
+        this.domainObject = handler.getDelegate();
+    }
+
+    protected Method intercept(final Method method) {
+        this.interceptedMethods.add(method);
+        return method;
+    }
+
+    protected Method veto(final Method method) {
+        this.vetoedMethods.add(method);
+        return method;
+    }
+
+    public String getCollectionName() {
+        return collectionName;
+    }
+
+    public OneToManyAssociation getCollection() {
+        return oneToManyAssociation;
+    }
+
+    public T getDomainObject() {
+        return domainObject;
+    }
+
+    @Override
+    public Object invoke(final Object collectionObject, final Method method, final Object[] args) throws Throwable {
+
+        // delegate
+        final Object returnValueObj = delegate(method, args);
+
+        if (interceptedMethods.contains(method)) {
+
+            resolveIfRequired(domainObject);
+
+            final InteractionEvent ev = new CollectionMethodEvent(getDelegate(), getCollection().getIdentifier(), getDomainObject(), method.getName(), args, returnValueObj);
+            notifyListeners(ev);
+            return returnValueObj;
+        }
+
+        if (vetoedMethods.contains(method)) {
+            throw new UnsupportedOperationException(String.format("Method '%s' may not be called directly.", method.getName()));
+        }
+
+        return returnValueObj;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
new file mode 100644
index 0000000..1646074
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
@@ -0,0 +1,71 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+
+/**
+ * Factory generating a mock for a class.
+ * <p>
+ * Note that this class is stateful
+ */
+public class CgLibClassProxyFactory<T> implements IProxyFactory<T> {
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final T toProxy, final InvocationHandler handler) {
+        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
+        return createProxy(proxyClass, handler);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final Class<T> toProxyClass, final InvocationHandler handler) {
+
+        final MethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
+
+        // Create the proxy
+        final Enhancer enhancer = new Enhancer();
+        enhancer.setSuperclass(toProxyClass);
+        enhancer.setInterfaces(new Class[] { WrapperObject.class });
+        enhancer.setCallbackType(interceptor.getClass());
+
+        final Class<?> enhancedClass = enhancer.createClass();
+
+        Enhancer.registerCallbacks(enhancedClass, new Callback[] { interceptor });
+
+        Factory factory;
+        try {
+            factory = (Factory) ClassInstantiatorFactoryCE.getInstantiator().newInstance(enhancedClass);
+        } catch (final InstantiationException e) {
+            throw new RuntimeException("Fail to instantiate mock for " + toProxyClass + " on " + ClassInstantiatorFactoryCE.getJVM() + " JVM");
+        }
+
+        return (T) factory;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
new file mode 100644
index 0000000..da4211c
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
@@ -0,0 +1,74 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.core.metamodel.specloader.classsubstitutor.CglibEnhanced;
+
+public class CgLibProxy<T> {
+
+    private final DelegatingInvocationHandler<T> handler;
+
+    public CgLibProxy(final DelegatingInvocationHandler<T> handler) {
+        this.handler = handler;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T proxy() {
+
+        final T toProxy = handler.getDelegate();
+
+        // handle if already proxied using cglib.
+        if (CglibEnhanced.class.isAssignableFrom(toProxy.getClass())) {
+
+            handler.setResolveObjectChangedEnabled(true);
+
+            final Class<? extends Object> enhancedClass = toProxy.getClass();
+            final Class<? extends Object> origSuperclass = toProxy.getClass().getSuperclass();
+
+            final List<Class> interfaces = new ArrayList<Class>();
+            interfaces.addAll(Arrays.asList(enhancedClass.getInterfaces()));
+            interfaces.remove(Factory.class); // if there.
+            interfaces.add(WrapperObject.class);
+
+            InvocationHandlerMethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
+            return (T) Enhancer.create(origSuperclass, interfaces.toArray(new Class[] {}), interceptor);
+        }
+
+        final Class<T> clazz = (Class<T>) toProxy.getClass();
+
+        T proxy = null;
+        try {
+            final IProxyFactory<T> proxyFactory = clazz.isInterface() ? new JavaProxyFactory<T>() : new CgLibClassProxyFactory<T>();
+            proxy = proxyFactory.createProxy(clazz, handler);
+        } catch (final RuntimeExceptionWrapper e) {
+            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
+        }
+        return proxy;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
new file mode 100644
index 0000000..85bc196
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
@@ -0,0 +1,65 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+/**
+ * Factory returning a {@link IClassInstantiatorCE}for the current JVM
+ */
+class ClassInstantiatorFactoryCE {
+
+    private static IClassInstantiatorCE instantiator = new ObjenesisClassInstantiatorCE();
+
+    // ///CLOVER:OFF
+    private ClassInstantiatorFactoryCE() {
+    }
+
+    // ///CLOVER:ON
+
+    /**
+     * Returns the current JVM as specified in the Systtem properties
+     * 
+     * @return current JVM
+     */
+    public static String getJVM() {
+        return System.getProperty("java.vm.vendor");
+    }
+
+    /**
+     * Returns the current JVM specification version (1.5, 1.4, 1.3)
+     * 
+     * @return current JVM specification version
+     */
+    public static String getJVMSpecificationVersion() {
+        return System.getProperty("java.specification.version");
+    }
+
+    public static boolean is1_3Specifications() {
+        return getJVMSpecificationVersion().equals("1.3");
+    }
+
+    /**
+     * Returns a class instantiator suitable for the current JVM
+     * 
+     * @return a class instantiator usable on the current JVM
+     */
+    public static IClassInstantiatorCE getInstantiator() {
+        return instantiator;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
new file mode 100644
index 0000000..d143af6
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.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.progmodel.wrapper.metamodel.internal;
+
+import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+class CollectionInvocationHandler<T, R> extends AbstractCollectionInvocationHandler<T, R> {
+
+    public CollectionInvocationHandler(final R collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionToProxy, collectionName, handler, otma);
+
+        try {
+            intercept(getMethod(collectionToProxy, "contains", Object.class));
+            intercept(getMethod(collectionToProxy, "size"));
+            intercept(getMethod(collectionToProxy, "isEmpty"));
+            if (collectionToProxy instanceof List) {
+                intercept(getMethod(collectionToProxy, "get", int.class));
+            }
+            veto(getMethod(collectionToProxy, "add", Object.class));
+            veto(getMethod(collectionToProxy, "remove", Object.class));
+            veto(getMethod(collectionToProxy, "addAll", Collection.class));
+            veto(getMethod(collectionToProxy, "removeAll", Collection.class));
+            veto(getMethod(collectionToProxy, "retainAll", Collection.class));
+            veto(getMethod(collectionToProxy, "clear"));
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
new file mode 100644
index 0000000..5772b88
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
@@ -0,0 +1,32 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+public interface DelegatingInvocationHandler<T> extends InvocationHandler {
+
+    T getDelegate();
+
+    public boolean isResolveObjectChangedEnabled();
+
+    public void setResolveObjectChangedEnabled(boolean resolveObjectChangedEnabled);
+
+}


[7/8] ISIS-409: fixing up build post moving wrapper service to core

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IClassInstantiatorCE.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IClassInstantiatorCE.java
new file mode 100644
index 0000000..9b471a5
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IClassInstantiatorCE.java
@@ -0,0 +1,37 @@
+/*
+ *  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.wrapper.internal;
+
+/**
+ * Used to instantiate a given class.
+ */
+interface IClassInstantiatorCE {
+
+    /**
+     * Return a new instance of the specified class. The recommended way is
+     * without calling any constructor. This is usually done by doing like
+     * <code>ObjectInputStream.readObject()</code> which is JVM specific.
+     * 
+     * @param c
+     *            Class to instantiate
+     * @return new instance of clazz
+     */
+    Object newInstance(Class<?> clazz) throws InstantiationException;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IProxyFactory.java
new file mode 100644
index 0000000..86c35f9
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/IProxyFactory.java
@@ -0,0 +1,28 @@
+/*
+ *  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.wrapper.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+public interface IProxyFactory<T> {
+    T createProxy(Class<T> toProxyClass, InvocationHandler handler);
+
+    T createProxy(T toProxy, InvocationHandler handler);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcher.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcher.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcher.java
new file mode 100644
index 0000000..04585d2
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcher.java
@@ -0,0 +1,28 @@
+/*
+ *  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.wrapper.internal;
+
+import org.apache.isis.applib.events.InteractionEvent;
+
+public interface InteractionEventDispatcher {
+
+    void dispatch(InteractionEvent interactionEvent);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcherTypeSafe.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcherTypeSafe.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcherTypeSafe.java
new file mode 100644
index 0000000..7fa3735
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InteractionEventDispatcherTypeSafe.java
@@ -0,0 +1,34 @@
+/*
+ *  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.wrapper.internal;
+
+import org.apache.isis.applib.events.InteractionEvent;
+
+public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> implements InteractionEventDispatcher {
+
+    public abstract void dispatchTypeSafe(T interactionEvent);
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void dispatch(final InteractionEvent interactionEvent) {
+        dispatchTypeSafe((T) interactionEvent);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InvocationHandlerMethodInterceptor.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InvocationHandlerMethodInterceptor.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InvocationHandlerMethodInterceptor.java
new file mode 100644
index 0000000..0cf6c82
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/InvocationHandlerMethodInterceptor.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.wrapper.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+public class InvocationHandlerMethodInterceptor implements MethodInterceptor {
+    private final InvocationHandler handler;
+
+    InvocationHandlerMethodInterceptor(final InvocationHandler handler) {
+        this.handler = handler;
+    }
+
+    @Override
+    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
+        return handler.invoke(obj, method, args);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/JavaProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/JavaProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/JavaProxyFactory.java
new file mode 100644
index 0000000..efeeb1d
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/JavaProxyFactory.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.wrapper.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+
+public class JavaProxyFactory<T> implements IProxyFactory<T> {
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final T toProxy, final InvocationHandler handler) {
+        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
+        return (T) Proxy.newProxyInstance(proxyClass.getClassLoader(), new Class[] { proxyClass }, handler);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final Class<T> toProxy, final InvocationHandler handler) {
+        return (T) Proxy.newProxyInstance(toProxy.getClassLoader(), new Class[] { toProxy, WrapperObject.class }, handler);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/MapInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/MapInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/MapInvocationHandler.java
new file mode 100644
index 0000000..b951347
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/MapInvocationHandler.java
@@ -0,0 +1,49 @@
+/*
+ *  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.wrapper.internal;
+
+import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
+
+import java.util.Map;
+
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+class MapInvocationHandler<T, C> extends AbstractCollectionInvocationHandler<T, C> {
+
+    public MapInvocationHandler(final C collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionToProxy, collectionName, handler, otma);
+
+        try {
+            intercept(getMethod(collectionToProxy, "containsKey", Object.class));
+            intercept(getMethod(collectionToProxy, "containsValue", Object.class));
+            intercept(getMethod(collectionToProxy, "size"));
+            intercept(getMethod(collectionToProxy, "isEmpty"));
+            veto(getMethod(collectionToProxy, "put", Object.class, Object.class));
+            veto(getMethod(collectionToProxy, "remove", Object.class));
+            veto(getMethod(collectionToProxy, "putAll", Map.class));
+            veto(getMethod(collectionToProxy, "clear"));
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ObjenesisClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ObjenesisClassInstantiatorCE.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ObjenesisClassInstantiatorCE.java
new file mode 100644
index 0000000..bd029d9
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/ObjenesisClassInstantiatorCE.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.wrapper.internal;
+
+import org.objenesis.ObjenesisHelper;
+
+class ObjenesisClassInstantiatorCE implements IClassInstantiatorCE {
+
+    @Override
+    public Object newInstance(final Class<?> clazz) throws InstantiationException {
+        return ObjenesisHelper.newInstance(clazz);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/Proxy.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/Proxy.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/Proxy.java
new file mode 100644
index 0000000..46952c6
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/Proxy.java
@@ -0,0 +1,80 @@
+/*
+ *  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.wrapper.internal;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.ensure.Ensure;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+public class Proxy {
+
+    public static <T> T proxy(final T domainObject, final WrapperFactory wrapperFactory, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager, final ObjectPersistor objectPersistor) {
+
+        Ensure.ensureThatArg(wrapperFactory, is(not(nullValue())));
+        Ensure.ensureThatArg(authenticationSessionProvider, is(not(nullValue())));
+        Ensure.ensureThatArg(specificationLookup, is(not(nullValue())));
+        Ensure.ensureThatArg(adapterManager, is(not(nullValue())));
+        Ensure.ensureThatArg(objectPersistor, is(not(nullValue())));
+
+        final DomainObjectInvocationHandler<T> invocationHandler = new DomainObjectInvocationHandler<T>(domainObject, wrapperFactory, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
+
+        final CgLibProxy<T> cglibProxy = new CgLibProxy<T>(invocationHandler);
+        return cglibProxy.proxy();
+    }
+
+    /**
+     * Whether to execute or not will be picked up from the supplied parent
+     * handler.
+     */
+    public static <T, E> Collection<E> proxy(final Collection<E> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+
+        final CollectionInvocationHandler<T, Collection<E>> collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(collectionToProxy, collectionName, handler, otma);
+        collectionInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+
+        final CgLibProxy<Collection<E>> cglibProxy = new CgLibProxy<Collection<E>>(collectionInvocationHandler);
+        return cglibProxy.proxy();
+    }
+
+    /**
+     * Whether to execute or not will be picked up from the supplied parent
+     * handler.
+     */
+    public static <T, P, Q> Map<P, Q> proxy(final Map<P, Q> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+
+        final MapInvocationHandler<T, Map<P, Q>> mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(collectionToProxy, collectionName, handler, otma);
+        mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+
+        final CgLibProxy<Map<P, Q>> cglibProxy = new CgLibProxy<Map<P, Q>>(mapInvocationHandler);
+        return cglibProxy.proxy();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/RuntimeExceptionWrapper.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/RuntimeExceptionWrapper.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/RuntimeExceptionWrapper.java
new file mode 100644
index 0000000..ef2feda
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/RuntimeExceptionWrapper.java
@@ -0,0 +1,33 @@
+/*
+ *  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.wrapper.internal;
+
+public class RuntimeExceptionWrapper extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private final RuntimeException runtimeException;
+
+    public RuntimeExceptionWrapper(final RuntimeException runtimeException) {
+        this.runtimeException = runtimeException;
+    }
+
+    public RuntimeException getRuntimeException() {
+        return runtimeException;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/Constants.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/Constants.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/Constants.java
new file mode 100644
index 0000000..0021038
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/Constants.java
@@ -0,0 +1,52 @@
+/*
+ *  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.wrapper.internal.util;
+
+public final class Constants {
+    private Constants() {
+    }
+
+    public static final String PREFIX_CHOICES = "choices";
+    public static final String PREFIX_DEFAULT = "default";
+    public static final String PREFIX_HIDE = "hide";
+    public static final String PREFIX_DISABLE = "disable";
+    public static final String PREFIX_VALIDATE_REMOVE_FROM = "validateRemoveFrom";
+    public static final String PREFIX_VALIDATE_ADD_TO = "validateAddTo";
+    public static final String PREFIX_VALIDATE = "validate";
+    public static final String PREFIX_REMOVE_FROM = "removeFrom";
+    public static final String PREFIX_ADD_TO = "addTo";
+    public static final String PREFIX_MODIFY = "modify";
+    public static final String PREFIX_CLEAR = "clear";
+    public static final String PREFIX_SET = "set";
+    public static final String PREFIX_GET = "get";
+
+    public final static String TITLE_METHOD_NAME = "title";
+    public final static String TO_STRING_METHOD_NAME = "toString";
+
+    /**
+     * Cannot invoke methods with these prefixes.
+     */
+    public final static String[] INVALID_PREFIXES = { PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, };
+
+    public final static String[] PROPERTY_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
+    public final static String[] COLLECTION_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_ADD_TO, PREFIX_REMOVE_FROM, PREFIX_DISABLE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
+    public final static String[] ACTION_PREFIXES = { PREFIX_VALIDATE, PREFIX_DISABLE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES, };
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/MethodPrefixFinder.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/MethodPrefixFinder.java b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/MethodPrefixFinder.java
new file mode 100644
index 0000000..dd78056
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/core/wrapper/internal/util/MethodPrefixFinder.java
@@ -0,0 +1,48 @@
+/*
+ *  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.wrapper.internal.util;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+
+public final class MethodPrefixFinder {
+
+    // a Linked Hash Set is used to ensure that the ordering is preserved.
+    public final static LinkedHashSet<String> ALL_PREFIXES = new LinkedHashSet<String>() {
+        private static final long serialVersionUID = 1L;
+        {
+            // collection prefixes are added first because we want to
+            // test validateAddTo and validateRemoveFrom before validate
+            addAll(Arrays.asList(Constants.COLLECTION_PREFIXES));
+            addAll(Arrays.asList(Constants.PROPERTY_PREFIXES));
+            addAll(Arrays.asList(Constants.ACTION_PREFIXES));
+        }
+    };
+
+    public String findPrefix(final String methodName) {
+        for (final String prefix : ALL_PREFIXES) {
+            if (methodName.startsWith(prefix)) {
+                return prefix;
+            }
+        }
+        return "";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
deleted file mode 100644
index 6b908c8..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel;
-
-import java.util.List;
-
-import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
-
-/**
- * A combined {@link DomainObjectContainer} and {@link WrapperFactory}.
- */
-public class DomainObjectContainerWrapperFactory extends DomainObjectContainerDefault implements WrapperFactory {
-
-    private final WrapperFactoryDefault wrapperFactoryDelegate;
-
-    public DomainObjectContainerWrapperFactory() {
-        this.wrapperFactoryDelegate = new WrapperFactoryDefault();
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Views
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public <T> T wrap(final T domainObject) {
-        return wrapperFactoryDelegate.wrap(domainObject);
-    }
-
-    @Override
-    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
-        return wrapperFactoryDelegate.wrap(domainObject, mode);
-    }
-
-    @Override
-    public boolean isWrapper(final Object possibleView) {
-        return wrapperFactoryDelegate.isWrapper(possibleView);
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Listeners
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public List<InteractionListener> getListeners() {
-        return wrapperFactoryDelegate.getListeners();
-    }
-
-    @Override
-    public boolean addInteractionListener(final InteractionListener listener) {
-        return wrapperFactoryDelegate.addInteractionListener(listener);
-    }
-
-    @Override
-    public boolean removeInteractionListener(final InteractionListener listener) {
-        return wrapperFactoryDelegate.removeInteractionListener(listener);
-    }
-
-    @Override
-    public void notifyListeners(final InteractionEvent interactionEvent) {
-        wrapperFactoryDelegate.notifyListeners(interactionEvent);
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Dependencies
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
-        super.setSpecificationLookup(specificationLookup);
-        wrapperFactoryDelegate.setSpecificationLookup(specificationLookup);
-    }
-
-    @Override
-    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
-        super.setAuthenticationSessionProvider(authenticationSessionProvider);
-        wrapperFactoryDelegate.setAuthenticationSessionProvider(authenticationSessionProvider);
-    }
-
-    @Override
-    public void setAdapterManager(final AdapterManager adapterManager) {
-        super.setAdapterManager(adapterManager);
-        wrapperFactoryDelegate.setAdapterManager(adapterManager);
-    }
-
-    @Override
-    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
-        super.setObjectPersistor(objectPersistor);
-        wrapperFactoryDelegate.setObjectPersistor(objectPersistor);
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
deleted file mode 100644
index 75e5fce..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.isis.applib.events.CollectionMethodEvent;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-abstract class AbstractCollectionInvocationHandler<T, C> extends DelegatingInvocationHandlerDefault<C> {
-
-    private final List<Method> interceptedMethods = new ArrayList<Method>();
-    private final List<Method> vetoedMethods = new ArrayList<Method>();
-    private final String collectionName;
-    private final OneToManyAssociation oneToManyAssociation;
-    private final T domainObject;
-
-    public AbstractCollectionInvocationHandler(final C collectionOrMapToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionOrMapToProxy, handler.getHeadlessViewer(), handler.getExecutionMode());
-        this.collectionName = collectionName;
-        this.oneToManyAssociation = otma;
-        this.domainObject = handler.getDelegate();
-    }
-
-    protected Method intercept(final Method method) {
-        this.interceptedMethods.add(method);
-        return method;
-    }
-
-    protected Method veto(final Method method) {
-        this.vetoedMethods.add(method);
-        return method;
-    }
-
-    public String getCollectionName() {
-        return collectionName;
-    }
-
-    public OneToManyAssociation getCollection() {
-        return oneToManyAssociation;
-    }
-
-    public T getDomainObject() {
-        return domainObject;
-    }
-
-    @Override
-    public Object invoke(final Object collectionObject, final Method method, final Object[] args) throws Throwable {
-
-        // delegate
-        final Object returnValueObj = delegate(method, args);
-
-        if (interceptedMethods.contains(method)) {
-
-            resolveIfRequired(domainObject);
-
-            final InteractionEvent ev = new CollectionMethodEvent(getDelegate(), getCollection().getIdentifier(), getDomainObject(), method.getName(), args, returnValueObj);
-            notifyListeners(ev);
-            return returnValueObj;
-        }
-
-        if (vetoedMethods.contains(method)) {
-            throw new UnsupportedOperationException(String.format("Method '%s' may not be called directly.", method.getName()));
-        }
-
-        return returnValueObj;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
deleted file mode 100644
index 1646074..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.MethodInterceptor;
-
-import org.apache.isis.applib.services.wrapper.WrapperObject;
-
-/**
- * Factory generating a mock for a class.
- * <p>
- * Note that this class is stateful
- */
-public class CgLibClassProxyFactory<T> implements IProxyFactory<T> {
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final T toProxy, final InvocationHandler handler) {
-        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
-        return createProxy(proxyClass, handler);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final Class<T> toProxyClass, final InvocationHandler handler) {
-
-        final MethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
-
-        // Create the proxy
-        final Enhancer enhancer = new Enhancer();
-        enhancer.setSuperclass(toProxyClass);
-        enhancer.setInterfaces(new Class[] { WrapperObject.class });
-        enhancer.setCallbackType(interceptor.getClass());
-
-        final Class<?> enhancedClass = enhancer.createClass();
-
-        Enhancer.registerCallbacks(enhancedClass, new Callback[] { interceptor });
-
-        Factory factory;
-        try {
-            factory = (Factory) ClassInstantiatorFactoryCE.getInstantiator().newInstance(enhancedClass);
-        } catch (final InstantiationException e) {
-            throw new RuntimeException("Fail to instantiate mock for " + toProxyClass + " on " + ClassInstantiatorFactoryCE.getJVM() + " JVM");
-        }
-
-        return (T) factory;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
deleted file mode 100644
index da4211c..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-
-import org.apache.isis.applib.services.wrapper.WrapperObject;
-import org.apache.isis.core.metamodel.specloader.classsubstitutor.CglibEnhanced;
-
-public class CgLibProxy<T> {
-
-    private final DelegatingInvocationHandler<T> handler;
-
-    public CgLibProxy(final DelegatingInvocationHandler<T> handler) {
-        this.handler = handler;
-    }
-
-    @SuppressWarnings("unchecked")
-    public T proxy() {
-
-        final T toProxy = handler.getDelegate();
-
-        // handle if already proxied using cglib.
-        if (CglibEnhanced.class.isAssignableFrom(toProxy.getClass())) {
-
-            handler.setResolveObjectChangedEnabled(true);
-
-            final Class<? extends Object> enhancedClass = toProxy.getClass();
-            final Class<? extends Object> origSuperclass = toProxy.getClass().getSuperclass();
-
-            final List<Class> interfaces = new ArrayList<Class>();
-            interfaces.addAll(Arrays.asList(enhancedClass.getInterfaces()));
-            interfaces.remove(Factory.class); // if there.
-            interfaces.add(WrapperObject.class);
-
-            InvocationHandlerMethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
-            return (T) Enhancer.create(origSuperclass, interfaces.toArray(new Class[] {}), interceptor);
-        }
-
-        final Class<T> clazz = (Class<T>) toProxy.getClass();
-
-        T proxy = null;
-        try {
-            final IProxyFactory<T> proxyFactory = clazz.isInterface() ? new JavaProxyFactory<T>() : new CgLibClassProxyFactory<T>();
-            proxy = proxyFactory.createProxy(clazz, handler);
-        } catch (final RuntimeExceptionWrapper e) {
-            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
-        }
-        return proxy;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
deleted file mode 100644
index 85bc196..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-/**
- * Factory returning a {@link IClassInstantiatorCE}for the current JVM
- */
-class ClassInstantiatorFactoryCE {
-
-    private static IClassInstantiatorCE instantiator = new ObjenesisClassInstantiatorCE();
-
-    // ///CLOVER:OFF
-    private ClassInstantiatorFactoryCE() {
-    }
-
-    // ///CLOVER:ON
-
-    /**
-     * Returns the current JVM as specified in the Systtem properties
-     * 
-     * @return current JVM
-     */
-    public static String getJVM() {
-        return System.getProperty("java.vm.vendor");
-    }
-
-    /**
-     * Returns the current JVM specification version (1.5, 1.4, 1.3)
-     * 
-     * @return current JVM specification version
-     */
-    public static String getJVMSpecificationVersion() {
-        return System.getProperty("java.specification.version");
-    }
-
-    public static boolean is1_3Specifications() {
-        return getJVMSpecificationVersion().equals("1.3");
-    }
-
-    /**
-     * Returns a class instantiator suitable for the current JVM
-     * 
-     * @return a class instantiator usable on the current JVM
-     */
-    public static IClassInstantiatorCE getInstantiator() {
-        return instantiator;
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
deleted file mode 100644
index d143af6..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-class CollectionInvocationHandler<T, R> extends AbstractCollectionInvocationHandler<T, R> {
-
-    public CollectionInvocationHandler(final R collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionToProxy, collectionName, handler, otma);
-
-        try {
-            intercept(getMethod(collectionToProxy, "contains", Object.class));
-            intercept(getMethod(collectionToProxy, "size"));
-            intercept(getMethod(collectionToProxy, "isEmpty"));
-            if (collectionToProxy instanceof List) {
-                intercept(getMethod(collectionToProxy, "get", int.class));
-            }
-            veto(getMethod(collectionToProxy, "add", Object.class));
-            veto(getMethod(collectionToProxy, "remove", Object.class));
-            veto(getMethod(collectionToProxy, "addAll", Collection.class));
-            veto(getMethod(collectionToProxy, "removeAll", Collection.class));
-            veto(getMethod(collectionToProxy, "retainAll", Collection.class));
-            veto(getMethod(collectionToProxy, "clear"));
-        } catch (final NoSuchMethodException e) {
-            // ///CLOVER:OFF
-            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
-            // ///CLOVER:ON
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
deleted file mode 100644
index 5772b88..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandler.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-
-public interface DelegatingInvocationHandler<T> extends InvocationHandler {
-
-    T getDelegate();
-
-    public boolean isResolveObjectChangedEnabled();
-
-    public void setResolveObjectChangedEnabled(boolean resolveObjectChangedEnabled);
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/55f931ae/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
deleted file mode 100644
index 93121ff..0000000
--- a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerObjectChanged;
-import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerResolve;
-
-public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocationHandler<T> {
-
-    private final T delegate;
-    protected final WrapperFactory wrapperFactory;
-    private final ExecutionMode executionMode;
-
-    protected final Method equalsMethod;
-    protected final Method hashCodeMethod;
-    protected final Method toStringMethod;
-
-    private final DomainObjectContainerObjectChanged domainObjectContainerObjectChanged;
-    private final DomainObjectContainerResolve domainObjectContainerResolve;
-
-    private boolean resolveObjectChangedEnabled;
-
-    public DelegatingInvocationHandlerDefault(final T delegate, final WrapperFactory headlessViewer, final ExecutionMode executionMode) {
-        if (delegate == null) {
-            throw new IllegalArgumentException("delegate must not be null");
-        }
-        this.delegate = delegate;
-        this.wrapperFactory = headlessViewer;
-        this.executionMode = executionMode;
-
-        this.domainObjectContainerResolve = new DomainObjectContainerResolve();
-        this.domainObjectContainerObjectChanged = new DomainObjectContainerObjectChanged();
-
-        try {
-            equalsMethod = delegate.getClass().getMethod("equals", new Class[] { Object.class });
-            hashCodeMethod = delegate.getClass().getMethod("hashCode", new Class[] {});
-            toStringMethod = delegate.getClass().getMethod("toString", new Class[] {});
-        } catch (final NoSuchMethodException e) {
-            // ///CLOVER:OFF
-            throw new RuntimeException("An Object method could not be found: " + e.getMessage());
-            // ///CLOVER:ON
-        }
-    }
-
-    @Override
-    public boolean isResolveObjectChangedEnabled() {
-        return resolveObjectChangedEnabled;
-    }
-
-    @Override
-    public void setResolveObjectChangedEnabled(final boolean resolveObjectChangedEnabled) {
-        this.resolveObjectChangedEnabled = resolveObjectChangedEnabled;
-    }
-
-    protected void resolveIfRequired(final ObjectAdapter targetAdapter) {
-        resolveIfRequired(targetAdapter.getObject());
-    }
-
-    protected void resolveIfRequired(final Object domainObject) {
-        if (resolveObjectChangedEnabled) {
-            domainObjectContainerResolve.resolve(domainObject);
-        }
-    }
-
-    protected void objectChangedIfRequired(final ObjectAdapter targetAdapter) {
-        objectChangedIfRequired(targetAdapter.getObject());
-    }
-
-    protected void objectChangedIfRequired(final Object domainObject) {
-        if (resolveObjectChangedEnabled) {
-            domainObjectContainerObjectChanged.objectChanged(domainObject);
-        }
-    }
-
-    public WrapperFactory getHeadlessViewer() {
-        return wrapperFactory;
-    }
-
-    @Override
-    public T getDelegate() {
-        return delegate;
-    }
-
-    public ExecutionMode getExecutionMode() {
-        return executionMode;
-    }
-
-    protected Object delegate(final Method method, final Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-
-        return method.invoke(getDelegate(), args);
-    }
-
-    protected boolean isObjectMethod(final Method method) {
-        return toStringMethod.equals(method) || hashCodeMethod.equals(method) || equalsMethod.equals(method);
-    }
-
-    @Override
-    public Object invoke(final Object object, final Method method, final Object[] args) throws Throwable {
-        return method.invoke(object, args);
-    }
-
-    protected InteractionEvent notifyListeners(final InteractionEvent interactionEvent) {
-        wrapperFactory.notifyListeners(interactionEvent);
-        return interactionEvent;
-    }
-
-}


[5/8] git commit: ISIS-409: moving wrapper progmodel into core, as a service

Posted by da...@apache.org.
ISIS-409: moving wrapper progmodel into core, as a service

* wrapper-applib stuff moves into isis-core-applib
* wrapper-progmodel becomes isis-core-wrapper
* also updated the junit-viewer stuff to use this code in its new location
* deleted the old parent progmodel-wrapper, no longer used
* updated the root (isis-all) pom.xml, no longer referenced deleted progmodel-wrapper.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/cd0735d2
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/cd0735d2
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/cd0735d2

Branch: refs/heads/master
Commit: cd0735d225b6f06da509e298c1a710927daf57ef
Parents: 4329dc8
Author: Dan Haywood <da...@apache.org>
Authored: Mon May 20 12:01:17 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Mon May 20 12:01:17 2013 +0100

----------------------------------------------------------------------
 component/progmodel/wrapper/NOTICE                 |    7 -
 component/progmodel/wrapper/pom.xml                |  127 ---
 .../appended-resources/supplemental-models.xml     |  106 ---
 component/progmodel/wrapper/src/site/apt/index.apt |   45 -
 .../progmodel/wrapper/src/site/apt/jottings.apt    |   24 -
 component/progmodel/wrapper/src/site/site.xml      |   45 -
 component/progmodel/wrapper/wrapper-applib/pom.xml |   77 --
 .../wrapper/applib/DisabledException.java          |   42 -
 .../progmodel/wrapper/applib/HiddenException.java  |   42 -
 .../wrapper/applib/InteractionException.java       |   75 --
 .../progmodel/wrapper/applib/InvalidException.java |   45 -
 .../progmodel/wrapper/applib/WrapperFactory.java   |  142 ----
 .../progmodel/wrapper/applib/WrapperObject.java    |   49 --
 .../applib/listeners/InteractionAdapter.java       |  109 ---
 .../applib/listeners/InteractionListener.java      |  194 -----
 .../wrapper/wrapper-applib/src/site/apt/index.apt  |   24 -
 .../wrapper-applib/src/site/apt/jottings.apt       |   24 -
 .../wrapper/wrapper-applib/src/site/site.xml       |   39 -
 .../progmodel/wrapper/wrapper-metamodel/pom.xml    |  121 ---
 .../DomainObjectContainerWrapperFactory.java       |  116 ---
 .../AbstractCollectionInvocationHandler.java       |   89 --
 .../metamodel/internal/CgLibClassProxyFactory.java |   71 --
 .../wrapper/metamodel/internal/CgLibProxy.java     |   74 --
 .../internal/ClassInstantiatorFactoryCE.java       |   65 --
 .../internal/CollectionInvocationHandler.java      |   54 --
 .../internal/DelegatingInvocationHandler.java      |   32 -
 .../DelegatingInvocationHandlerDefault.java        |  131 ---
 .../internal/DomainObjectInvocationHandler.java    |  645 ---------------
 .../metamodel/internal/IClassInstantiatorCE.java   |   37 -
 .../wrapper/metamodel/internal/IProxyFactory.java  |   28 -
 .../internal/InteractionEventDispatcher.java       |   28 -
 .../InteractionEventDispatcherTypeSafe.java        |   34 -
 .../InvocationHandlerMethodInterceptor.java        |   39 -
 .../metamodel/internal/JavaProxyFactory.java       |   40 -
 .../metamodel/internal/MapInvocationHandler.java   |   49 --
 .../internal/ObjenesisClassInstantiatorCE.java     |   31 -
 .../wrapper/metamodel/internal/Proxy.java          |   80 --
 .../internal/RuntimeExceptionWrapper.java          |   33 -
 .../metamodel/internal/WrapperFactoryDefault.java  |  271 ------
 .../wrapper/metamodel/internal/util/Constants.java |   52 --
 .../internal/util/MethodPrefixFinder.java          |   48 --
 .../wrapper-metamodel/src/site/apt/index.apt       |   22 -
 .../wrapper-metamodel/src/site/apt/jottings.apt    |   24 -
 .../wrapper/wrapper-metamodel/src/site/site.xml    |   39 -
 .../WrappedFactoryDefaultTest_wrappedObject.java   |  153 ----
 ...FactoryDefaultTest_wrappedObject_transient.java |  251 ------
 component/viewer/junit/impl/pom.xml                |    4 +-
 .../org/apache/isis/viewer/junit/AbstractTest.java |    2 +-
 .../isis/viewer/junit/InteractionListenerTest.java |    4 +-
 .../isis/viewer/junit/MemberDisabledTest.java      |    2 +-
 .../apache/isis/viewer/junit/MemberHiddenTest.java |    2 +-
 .../isis/viewer/junit/MemberInvalidTest.java       |    2 +-
 .../apache/isis/viewer/junit/MemberModifyTest.java |    2 +-
 .../isis/viewer/junit/ObjectImmutableTest.java     |    2 +-
 .../apache/isis/viewer/junit/SaveObjectsTest.java  |    4 +-
 .../apache/isis/viewer/junit/ViewObjectTest.java   |    2 +-
 .../tck/src/test/java/junit/AbstractTest.java      |    4 +-
 .../applib/services/wrapper/DisabledException.java |   42 +
 .../applib/services/wrapper/HiddenException.java   |   42 +
 .../services/wrapper/InteractionException.java     |   75 ++
 .../applib/services/wrapper/InvalidException.java  |   45 +
 .../applib/services/wrapper/WrapperFactory.java    |  142 ++++
 .../applib/services/wrapper/WrapperObject.java     |   49 ++
 .../wrapper/listeners/InteractionAdapter.java      |  109 +++
 .../wrapper/listeners/InteractionListener.java     |  194 +++++
 core/pom.xml                                       |   12 +-
 core/wrapper/pom.xml                               |  115 +++
 .../DomainObjectContainerWrapperFactory.java       |  116 +++
 .../AbstractCollectionInvocationHandler.java       |   89 ++
 .../metamodel/internal/CgLibClassProxyFactory.java |   71 ++
 .../wrapper/metamodel/internal/CgLibProxy.java     |   74 ++
 .../internal/ClassInstantiatorFactoryCE.java       |   65 ++
 .../internal/CollectionInvocationHandler.java      |   54 ++
 .../internal/DelegatingInvocationHandler.java      |   32 +
 .../DelegatingInvocationHandlerDefault.java        |  131 +++
 .../internal/DomainObjectInvocationHandler.java    |  645 +++++++++++++++
 .../metamodel/internal/IClassInstantiatorCE.java   |   37 +
 .../wrapper/metamodel/internal/IProxyFactory.java  |   28 +
 .../internal/InteractionEventDispatcher.java       |   28 +
 .../InteractionEventDispatcherTypeSafe.java        |   34 +
 .../InvocationHandlerMethodInterceptor.java        |   39 +
 .../metamodel/internal/JavaProxyFactory.java       |   40 +
 .../metamodel/internal/MapInvocationHandler.java   |   49 ++
 .../internal/ObjenesisClassInstantiatorCE.java     |   31 +
 .../wrapper/metamodel/internal/Proxy.java          |   80 ++
 .../internal/RuntimeExceptionWrapper.java          |   33 +
 .../metamodel/internal/WrapperFactoryDefault.java  |  271 ++++++
 .../wrapper/metamodel/internal/util/Constants.java |   52 ++
 .../internal/util/MethodPrefixFinder.java          |   48 ++
 core/wrapper/src/site/apt/index.apt                |   22 +
 core/wrapper/src/site/apt/jottings.apt             |   24 +
 core/wrapper/src/site/site.xml                     |   39 +
 .../WrappedFactoryDefaultTest_wrappedObject.java   |  153 ++++
 ...FactoryDefaultTest_wrappedObject_transient.java |  251 ++++++
 .../isis/example/claims/junit/AbstractTest.java    |    4 +-
 .../isis/example/claims/junit/ClaimSubmitTest.java |    2 +-
 .../src/test/java/junit/AbstractTest.java          |    4 +-
 .../src/test/java/junit/todo/ToDoItemTest.java     |    2 +-
 pom.xml                                            |    1 -
 99 files changed, 3381 insertions(+), 3896 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/NOTICE
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/NOTICE b/component/progmodel/wrapper/NOTICE
deleted file mode 100644
index ba21d0c..0000000
--- a/component/progmodel/wrapper/NOTICE
+++ /dev/null
@@ -1,7 +0,0 @@
-Apache Isis
-Copyright 2010-2013 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/pom.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/pom.xml b/component/progmodel/wrapper/pom.xml
deleted file mode 100644
index 265c261..0000000
--- a/component/progmodel/wrapper/pom.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-	<parent>
-		<groupId>org.apache.isis.core</groupId>
-		<artifactId>isis</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-		<relativePath>../../../core/pom.xml</relativePath>
-	</parent>
-
-
-	<groupId>org.apache.isis.progmodel</groupId>
-	<artifactId>isis-progmodel-wrapper</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
-
-	<name>Isis Wrapper ProgModel</name>
-
-	<packaging>pom</packaging>
-
-	<properties>
-        <siteBaseDir>.</siteBaseDir>
-		<relativeUrl/>
-    </properties>
-
-    <!-- used in Site generation for relative references. -->
-    <url>http://isis.apache.org/${relativeUrl}</url>
-
-	<build>
-		<pluginManagement>
-			<plugins>
-                <!-- Apache Release Audit Tool -->
-                <plugin>
-                    <groupId>org.apache.rat</groupId>
-                    <artifactId>apache-rat-plugin</artifactId>
-                    <version>0.8</version>
-	                <configuration>
-	                    <excludes>
-	                    	<!-- 
-	                    	overriding inherited excludes from oia.core:isis 
-	                    	with a more specific set for this component
-	                    	 -->
-	                        <exclude>**/target/**</exclude>
-	                        <exclude>**/target-ide/**</exclude>
-
-	                        <exclude>**/*.project</exclude>
-	                        <exclude>**/.classpath</exclude>
-	                        <exclude>**/.settings/**</exclude>
-	                    </excludes>
-                    </configuration>
-	            </plugin>
-			</plugins>
-		</pluginManagement>
-	</build>
-
-	<modules>
-		<module>wrapper-applib</module>
-		<module>wrapper-metamodel</module>
-	</modules>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-project-info-reports-plugin</artifactId>
-				<version>${maven-project-info-reports-plugin}</version>
-                <inherited>false</inherited>
-                <reportSets>
-                    <reportSet>
-                        <inherited>false</inherited>
-                        <reports>
-                            <report>dependency-management</report>
-                            <report>plugins</report>
-                            <report>modules</report>
-                            <report>summary</report>
-                        </reports>
-                    </reportSet>
-                </reportSets>
-            </plugin>
-        </plugins>
-    </reporting>
-
-
-    <dependencyManagement>
-        <dependencies>
-
-	    	<!-- for benefit of application developers, using scope=import -->
-			<dependency>
-				<groupId>${project.groupId}</groupId>
-				<artifactId>isis-progmodel-wrapper-applib</artifactId>
-	            <version>1.0.0-SNAPSHOT</version>
-			</dependency>
-			<dependency>
-				<groupId>${project.groupId}</groupId>
-				<artifactId>isis-progmodel-wrapper-applib</artifactId>
-				<version>${project.version}</version>
-				<type>test-jar</type>
-                <scope>test</scope>
-			</dependency>
-			<dependency>
-				<groupId>${project.groupId}</groupId>
-				<artifactId>isis-progmodel-wrapper-impl</artifactId>
-	            <version>1.0.0-SNAPSHOT</version>
-			</dependency>
-
-
-		</dependencies>
-	</dependencyManagement>
-</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/src/main/appended-resources/supplemental-models.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/src/main/appended-resources/supplemental-models.xml b/component/progmodel/wrapper/src/main/appended-resources/supplemental-models.xml
deleted file mode 100644
index ecd3906..0000000
--- a/component/progmodel/wrapper/src/main/appended-resources/supplemental-models.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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. -->
-<supplementalDataModels xmlns="http://maven.apache.org/supplemental-model/1.0.0"
-                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-                        xsi:schemaLocation="http://maven.apache.org/supplemental-model/1.0.0 http://maven.apache.org/xsd/supplemental-model-1.0.0.xsd">
-
-  <supplement>
-    <project>
-      <groupId>aopalliance</groupId>
-      <artifactId>aopalliance</artifactId>
-      <version>1.0</version>
-      <licenses>
-          <license>
-              <name>Public Domain</name>
-          </license>
-      </licenses>
-    </project>
-  </supplement>
-
-  <supplement>
-   	<!-- not quite sure why licenses:download-license flags this, since license info seems to be in its POM -->
-    <project>
-		<groupId>org.datanucleus</groupId>
-	    <artifactId>datanucleus-jodatime</artifactId>
-	    <version>3.1.1</version>
-          <licenses>
-			<license>
-	            <name>The Apache Software License, Version 2.0</name>
-	            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-	        </license>
-	    </licenses>
-    </project>
-  </supplement>
-
-  <supplement>
-    <project>
-      <groupId>org.scannotation</groupId>
-      <artifactId>scannotation</artifactId>
-      <version>1.0.3</version>
-      <licenses>
-        <license>
-            <name>The Apache Software License, Version 2.0</name>
-            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-            <distribution>repo</distribution>          
-        </license>
-      </licenses>
-    </project>
-  </supplement>
-    
-  <supplement>
-    <project>
-      <groupId>dom4j</groupId>
-      <artifactId>dom4j</artifactId>
-      <version>1.6.1</version>
-      <licenses>
-        <license>
-            <name>BSD License</name>
-            <url>http://dom4j.sourceforge.net/dom4j-1.6.1/license.html</url>
-            <distribution>repo</distribution>          
-        </license>
-      </licenses>
-    </project>
-  </supplement>
-
-  <supplement>
-    <project>
-      <groupId>net.jcip</groupId>
-      <artifactId>jcip-annotations</artifactId>
-      <version>1.0</version>
-      <licenses>
-        <license>
-            <name>Creative Commons Attribution 2.5 License</name>
-            <url>http://creativecommons.org/licenses/by/2.5/</url>
-            <distribution>repo</distribution>          
-        </license>
-      </licenses>
-    </project>
-  </supplement>
-  
-
-  <supplement>
-    <project>
-      <groupId>xalan</groupId>
-      <artifactId>xalan</artifactId>
-      <version>2.7.0</version>
-      <licenses>
-        <license>
-            <name>The Apache Software License, Version 2.0</name>
-            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-            <distribution>repo</distribution>          
-        </license>
-      </licenses>
-    </project>
-  </supplement>
-
- 
-</supplementalDataModels>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/src/site/apt/index.apt b/component/progmodel/wrapper/src/site/apt/index.apt
deleted file mode 100644
index 3cbbd45..0000000
--- a/component/progmodel/wrapper/src/site/apt/index.apt
+++ /dev/null
@@ -1,45 +0,0 @@
-~~  Licensed to the Apache Software Foundation (ASF) under one
-~~  or more contributor license agreements.  See the NOTICE file
-~~  distributed with this work for additional information
-~~  regarding copyright ownership.  The ASF licenses this file
-~~  to you under the Apache License, Version 2.0 (the
-~~  "License"); you may not use this file except in compliance
-~~  with the License.  You may obtain a copy of the License at
-~~
-~~        http://www.apache.org/licenses/LICENSE-2.0
-~~
-~~  Unless required by applicable law or agreed to in writing,
-~~  software distributed under the License is distributed on an
-~~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-~~  KIND, either express or implied.  See the License for the
-~~  specific language governing permissions and limitations
-~~  under the License.
-
-
-
-Wrapper Programming Model
- 
- The <wrapper> programming model allows a domain object to be "wrapped" so that when another domain object interact with it,
- it is <as if> through a viewer.  That is, if a property or action is unusable on the wrapped domain object, then the 
- calling domain object will be receive an exception indicating the fact.
- 
- The wrapper programming model is provided as an implementation of Isis' <<<DomainObjectContainer>>> interface (in the
- {{{../../applib/index.html}applib}}.  
- This can be downcast into a <<<WrapperFactory>>>, from which the domain object is wrapped using a {{{http://cglib.sourceforge.net/}CgLib}} proxy.  
- This proxy implements the checks to ensure that the wrapped object is visible, is not disabled, and the interaction is
- valid ("see it, use it, do it").
-
-Alternatives
-
-  Alternatives include:
-  
-  * the {{{../dflt/index.html}default}} programming model.
-  
-  * the {{{../groovy/index.html}wrapper}} programming model.
-  
-    For domain objects written with Groovy.
-
-  []
-  
-  Note that these are <i>not</i> necessarily mutually exclusive (they can be combined). 
- 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/src/site/apt/jottings.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/src/site/apt/jottings.apt b/component/progmodel/wrapper/src/site/apt/jottings.apt
deleted file mode 100644
index c5d1200..0000000
--- a/component/progmodel/wrapper/src/site/apt/jottings.apt
+++ /dev/null
@@ -1,24 +0,0 @@
-~~  Licensed to the Apache Software Foundation (ASF) under one
-~~  or more contributor license agreements.  See the NOTICE file
-~~  distributed with this work for additional information
-~~  regarding copyright ownership.  The ASF licenses this file
-~~  to you under the Apache License, Version 2.0 (the
-~~  "License"); you may not use this file except in compliance
-~~  with the License.  You may obtain a copy of the License at
-~~
-~~        http://www.apache.org/licenses/LICENSE-2.0
-~~
-~~  Unless required by applicable law or agreed to in writing,
-~~  software distributed under the License is distributed on an
-~~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-~~  KIND, either express or implied.  See the License for the
-~~  specific language governing permissions and limitations
-~~  under the License.
-
-
-
-Jottings
- 
-  This page is to capture any random jottings relating to this module prior 
-  to being moved into formal documentation. 
- 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/src/site/site.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/src/site/site.xml b/component/progmodel/wrapper/src/site/site.xml
deleted file mode 100644
index f9cf5e7..0000000
--- a/component/progmodel/wrapper/src/site/site.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project>
-
-	<body>
-		<breadcrumbs>
-			<item name="Wrapper" href="index.html"/>
-		</breadcrumbs>
-
-		<menu name="Wrapper Progmodel">
-			<item name="About" href="index.html" />
-            <item name="Jottings" href="jottings.html" />
-		</menu>
-
-        <menu name="Progmodel Modules">
-            <item name="Default (Java)" href="../dflt/index.html" />
-            <item name="Groovy" href="../groovy/index.html" />
-            <item name="Wrapper" href="../wrapper/index.html" />
-        </menu>
-        
-        <menu name="Wrapper Modules">
-            <item name="Applib" href="./wrapper-applib/index.html" />
-            <item name="Metamodel" href="./wrapper-metamodel/index.html" />
-        </menu>
-
-        <menu name="Maven Reports" ref="reports" />
-	</body>
-</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/pom.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/pom.xml b/component/progmodel/wrapper/wrapper-applib/pom.xml
deleted file mode 100644
index 409f70c..0000000
--- a/component/progmodel/wrapper/wrapper-applib/pom.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.isis.progmodel</groupId>
-        <artifactId>isis-progmodel-wrapper</artifactId>
-        <version>1.0.0-SNAPSHOT</version>
-	</parent>
-
-	<artifactId>isis-progmodel-wrapper-applib</artifactId>
-	<name>Isis Wrapper ProgModel Applib</name>
-	<description>Isis Wrapper ProgModel Applib</description>
-
-
-    <!-- shouldn't be needed, but was being built as a pom for some reason -->
-    <packaging>jar</packaging>
-
-	<properties>
-        <siteBaseDir>..</siteBaseDir>
-		<relativeUrl>wrapper-applib/</relativeUrl>
-	</properties>
-
-    <!-- used in Site generation for relative references. -->
-    <url>http://isis.apache.org/${relativeUrl}</url>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-project-info-reports-plugin</artifactId>
-				<version>${maven-project-info-reports-plugin}</version>
-                <inherited>false</inherited>
-                <configuration>
-                	<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
-                </configuration>
-                <reportSets>
-                    <reportSet>
-                        <inherited>false</inherited>
-                        <reports>
-                            <report>dependencies</report>
-                            <report>dependency-convergence</report>
-                            <report>plugins</report>
-                            <report>summary</report>
-                        </reports>
-                    </reportSet>
-                </reportSets>
-            </plugin>
-        </plugins>
-    </reporting>
-
-	<dependencies>
-		<dependency>
-			<groupId>org.apache.isis.core</groupId>
-			<artifactId>isis-core-applib</artifactId>
-        </dependency>
-	</dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/DisabledException.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/DisabledException.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/DisabledException.java
deleted file mode 100644
index b2cc3ff..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/DisabledException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib;
-
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.UsabilityEvent;
-
-/**
- * Superclass of exceptions which indicate an attempt to interact with a class
- * member that is disabled.
- */
-public class DisabledException extends InteractionException {
-
-    private static final long serialVersionUID = 1L;
-
-    public DisabledException(final InteractionEvent interactionEvent) {
-        super(interactionEvent);
-    }
-
-    @Override
-    public UsabilityEvent getInteractionEvent() {
-        return (UsabilityEvent) super.getInteractionEvent();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/HiddenException.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/HiddenException.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/HiddenException.java
deleted file mode 100644
index 9d3c451..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/HiddenException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib;
-
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.VisibilityEvent;
-
-/**
- * Superclass of exceptions which indicate an attempt to interact with a class
- * member that is in some way hidden or invisible.
- */
-public class HiddenException extends InteractionException {
-
-    private static final long serialVersionUID = 1L;
-
-    public HiddenException(final InteractionEvent interactionEvent) {
-        super(interactionEvent);
-    }
-
-    @Override
-    public VisibilityEvent getInteractionEvent() {
-        return (VisibilityEvent) super.getInteractionEvent();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InteractionException.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InteractionException.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InteractionException.java
deleted file mode 100644
index 3931d05..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InteractionException.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib;
-
-import org.apache.isis.applib.ApplicationException;
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.events.InteractionEvent;
-
-public abstract class InteractionException extends ApplicationException {
-
-    private static final long serialVersionUID = 1L;
-
-    private final InteractionEvent interactionEvent;
-
-    public InteractionException(final InteractionEvent interactionEvent) {
-        super(interactionEvent.getReason());
-        this.interactionEvent = interactionEvent;
-    }
-
-    /**
-     * The {@link InteractionEvent event} passed into the
-     * {@link #InteractionException(InteractionEvent) constructor}.
-     * 
-     * <p>
-     * Not part of the API, but made available so that subclasses can expose as
-     * the appropriate subtype of {@link InteractionEvent}. This would have been
-     * more obvious to see if {@link InteractionException} was generic, but
-     * generic subclasses of {@link Throwable} are (apparently) not allowed.
-     * 
-     * @return
-     */
-    protected InteractionEvent getInteractionEvent() {
-        return interactionEvent;
-    }
-
-    /**
-     * Convenience method that returns the
-     * {@link InteractionEvent#getAdvisorClass() advisor class} of the wrapped
-     * {@link #getInteractionEvent() interaction event}.
-     * 
-     * @return
-     */
-    public Class<?> getAdvisorClass() {
-        return interactionEvent.getAdvisorClass();
-    }
-
-    /**
-     * Convenience method that returns the
-     * {@link InteractionEvent#getIdentifier() identifier} of the wrapped
-     * {@link #getInteractionEvent() interaction event}.
-     * 
-     * @return
-     */
-    public Identifier getIdentifier() {
-        return interactionEvent.getIdentifier();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InvalidException.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InvalidException.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InvalidException.java
deleted file mode 100644
index d8aa401..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/InvalidException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib;
-
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.applib.events.ValidityEvent;
-
-/**
- * Superclass of exceptions which indicate an attempt to interact with an object
- * or member in a way that is invalid.
- * 
- * <p>
- * 
- */
-public class InvalidException extends InteractionException {
-
-    private static final long serialVersionUID = 1L;
-
-    public InvalidException(final InteractionEvent interactionEvent) {
-        super(interactionEvent);
-    }
-
-    @Override
-    public ValidityEvent getInteractionEvent() {
-        return (ValidityEvent) super.getInteractionEvent();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperFactory.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperFactory.java
deleted file mode 100644
index fe5e7a2..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperFactory.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib;
-
-import java.util.List;
-
-import org.apache.isis.applib.annotation.Hidden;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.progmodel.wrapper.applib.listeners.InteractionListener;
-
-/**
- * Provides the ability to &quot;wrap&quot; of a domain object such that it can
- * be interacted with while enforcing the hide/disable/validate rules implies by
- * the Isis programming model.
- * 
- * <p>
- * The &quot;wrap&quot; is a CGLib proxy that wraps the underlying domain
- * object. The wrapper can then be interacted with as follows:
- * <ul>
- * <li>a <tt>get</tt> method for properties or collections</li>
- * <li>a <tt>set</tt> method for properties</li>
- * <li>an <tt>addTo</tt> or <tt>removeFrom</tt> method for collections</li>
- * <li>any action</li>
- * </ul>
- * 
- * <p>
- * Calling any of the above methods may result in a (subclass of)
- * {@link InteractionException} if the object disallows it. For example, if a
- * property is annotated with {@link Hidden} then a {@link HiddenException} will
- * be thrown. Similarly if an action has a <tt>validate</tt> method and the
- * supplied arguments are invalid then a {@link InvalidException} will be
- * thrown.
- * 
- * <p>
- * In addition, the following methods may also be called:
- * <ul>
- * <li>the <tt>title</tt> method</li>
- * <li>any <tt>defaultXxx</tt> or <tt>choicesXxx</tt> method</li>
- * </ul>
- * 
- * <p>
- * An exception will be thrown if any other methods are thrown.
- */
-public interface WrapperFactory {
-
-    /**
-     * Whether interactions with the wrapper are actually passed onto the
-     * underlying domain object.
-     * 
-     * @see WrapperFactory#wrap(Object, ExecutionMode)
-     */
-    public static enum ExecutionMode {
-        EXECUTE, NO_EXECUTE
-    }
-
-    /**
-     * Provides the &quot;wrapper&quot; of the underlying domain object.
-     * 
-     * <p>
-     * If the object has (see {@link #isWrapper(Object)} already been wrapped),
-     * then should just return the object back unchanged.
-     * 
-     * @see #addInteractionListener(InteractionListener)
-     */
-    <T> T wrap(T domainObject);
-
-    /**
-     * Same as {@link #wrap(Object)}, except the actual execution occurs only if
-     * the <tt>execute</tt> parameter indicates.
-     * 
-     * <p>
-     * Otherwise, will do all the validations (raise exceptions as required
-     * etc.), but doesn't modify the model.
-     */
-    <T> T wrap(T domainObject, ExecutionMode mode);
-
-    /**
-     * Whether the supplied object has been wrapped.
-     * 
-     * @param <T>
-     * @param possibleWrapper
-     *            - object that might or might not be a wrapper.
-     * @return
-     */
-    <T> boolean isWrapper(T possibleWrapper);
-
-    /**
-     * All {@link InteractionListener}s that have been registered using
-     * {@link #addInteractionListener(InteractionListener)}.
-     */
-    List<InteractionListener> getListeners();
-
-    /**
-     * Registers an {@link InteractionListener}, to be notified of interactions
-     * on all wrappers.
-     * 
-     * <p>
-     * This is retrospective: the listener will be notified of interactions even
-     * on wrappers created before the listener was installed. (From an
-     * implementation perspective this is because the wrappers delegate back to
-     * the container to fire the events).
-     * 
-     * @param listener
-     * @return
-     */
-    public boolean addInteractionListener(InteractionListener listener);
-
-    /**
-     * Remove an {@link InteractionListener}, to no longer be notified of
-     * interactions on wrappers.
-     * 
-     * <p>
-     * This is retrospective: the listener will no longer be notified of any
-     * interactions created on any wrappers, not just on those wrappers created
-     * subsequently. (From an implementation perspective this is because the
-     * wrappers delegate back to the container to fire the events).
-     * 
-     * @param listener
-     * @return
-     */
-    public boolean removeInteractionListener(InteractionListener listener);
-
-    public void notifyListeners(InteractionEvent ev);
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperObject.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperObject.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperObject.java
deleted file mode 100644
index a4e01ae..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/WrapperObject.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib;
-
-/**
- * Implemented by all objects that have been viewed as per
- * {@link WrapperFactory#wrap(Object)}.
- */
-public interface WrapperObject {
-
-    /**
-     * Programmatic equivalent of invoking save for a transient object (that is,
-     * like hitting the <i>save</i> button that the DnD viewer automatically
-     * renders.
-     */
-    void save();
-
-    /**
-     * Provide access to the underlying, wrapped object.
-     * 
-     * <p>
-     * Used to unwrap objects used as arguments to actions (otherwise, end up
-     * creating a <tt>ObjectSpecification</tt> for the CGLib-enhanced class, not
-     * the original class).
-     * 
-     * <p>
-     * <b>NOTE: there is a string-literal reference to this name
-     * <tt>DomainObjectInvocationHandler</tt>, so it should not be changed.</b>.
-     */
-    Object wrapped();
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionAdapter.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionAdapter.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionAdapter.java
deleted file mode 100644
index db14735..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionAdapter.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib.listeners;
-
-import org.apache.isis.applib.events.ActionArgumentEvent;
-import org.apache.isis.applib.events.ActionInvocationEvent;
-import org.apache.isis.applib.events.ActionUsabilityEvent;
-import org.apache.isis.applib.events.ActionVisibilityEvent;
-import org.apache.isis.applib.events.CollectionAccessEvent;
-import org.apache.isis.applib.events.CollectionAddToEvent;
-import org.apache.isis.applib.events.CollectionMethodEvent;
-import org.apache.isis.applib.events.CollectionRemoveFromEvent;
-import org.apache.isis.applib.events.CollectionUsabilityEvent;
-import org.apache.isis.applib.events.CollectionVisibilityEvent;
-import org.apache.isis.applib.events.ObjectTitleEvent;
-import org.apache.isis.applib.events.ObjectValidityEvent;
-import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.applib.events.PropertyModifyEvent;
-import org.apache.isis.applib.events.PropertyUsabilityEvent;
-import org.apache.isis.applib.events.PropertyVisibilityEvent;
-
-/**
- * Provides no-op implementations of each of the methods within
- * {@link InteractionListener}, to simplify the creation of new listeners.
- */
-public class InteractionAdapter implements InteractionListener {
-
-    @Override
-    public void propertyVisible(final PropertyVisibilityEvent ev) {
-    }
-
-    @Override
-    public void propertyUsable(final PropertyUsabilityEvent ev) {
-    }
-
-    @Override
-    public void propertyAccessed(final PropertyAccessEvent ev) {
-    }
-
-    @Override
-    public void propertyModified(final PropertyModifyEvent ev) {
-    }
-
-    @Override
-    public void collectionVisible(final CollectionVisibilityEvent ev) {
-    }
-
-    @Override
-    public void collectionUsable(final CollectionUsabilityEvent ev) {
-    }
-
-    @Override
-    public void collectionAccessed(final CollectionAccessEvent ev) {
-    }
-
-    @Override
-    public void collectionAddedTo(final CollectionAddToEvent ev) {
-    }
-
-    @Override
-    public void collectionRemovedFrom(final CollectionRemoveFromEvent ev) {
-    }
-
-    @Override
-    public void collectionMethodInvoked(final CollectionMethodEvent interactionEvent) {
-    }
-
-    @Override
-    public void actionVisible(final ActionVisibilityEvent interactionEvent) {
-    }
-
-    @Override
-    public void actionUsable(final ActionUsabilityEvent ev) {
-    }
-
-    @Override
-    public void actionArgument(final ActionArgumentEvent ev) {
-    }
-
-    @Override
-    public void actionInvoked(final ActionInvocationEvent ev) {
-    }
-
-    @Override
-    public void objectPersisted(final ObjectValidityEvent ev) {
-    }
-
-    @Override
-    public void objectTitleRead(final ObjectTitleEvent ev) {
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionListener.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionListener.java b/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionListener.java
deleted file mode 100644
index 58a1228..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/main/java/org/apache/isis/progmodel/wrapper/applib/listeners/InteractionListener.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.applib.listeners;
-
-import org.apache.isis.applib.events.ActionArgumentEvent;
-import org.apache.isis.applib.events.ActionInvocationEvent;
-import org.apache.isis.applib.events.ActionUsabilityEvent;
-import org.apache.isis.applib.events.ActionVisibilityEvent;
-import org.apache.isis.applib.events.CollectionAccessEvent;
-import org.apache.isis.applib.events.CollectionAddToEvent;
-import org.apache.isis.applib.events.CollectionMethodEvent;
-import org.apache.isis.applib.events.CollectionRemoveFromEvent;
-import org.apache.isis.applib.events.CollectionUsabilityEvent;
-import org.apache.isis.applib.events.CollectionVisibilityEvent;
-import org.apache.isis.applib.events.ObjectTitleEvent;
-import org.apache.isis.applib.events.ObjectValidityEvent;
-import org.apache.isis.applib.events.PropertyAccessEvent;
-import org.apache.isis.applib.events.PropertyModifyEvent;
-import org.apache.isis.applib.events.PropertyUsabilityEvent;
-import org.apache.isis.applib.events.PropertyVisibilityEvent;
-
-public interface InteractionListener {
-
-    /**
-     * The title was read.
-     * 
-     * @param ev
-     */
-    void objectTitleRead(ObjectTitleEvent ev);
-
-    /**
-     * The object was persisted (or an attempt to persist it was made).
-     * 
-     * @param ev
-     */
-    void objectPersisted(ObjectValidityEvent ev);
-
-    /**
-     * A check was made to determine if a property was visible.
-     * 
-     * @param ev
-     */
-    void propertyVisible(PropertyVisibilityEvent ev);
-
-    /**
-     * A check was made to determine if a property was usable.
-     * 
-     * @param ev
-     */
-    void propertyUsable(PropertyUsabilityEvent ev);
-
-    /**
-     * A property was read.
-     * 
-     * <p>
-     * Unlike most other events, a {@link PropertyAccessEvent} will never have
-     * been vetoed (that is, {@link PropertyAccessEvent#isVeto()} will always be
-     * <tt>false</tt>).
-     * 
-     * @param ev
-     */
-    void propertyAccessed(PropertyAccessEvent ev);
-
-    /**
-     * A property was modified (or an attempt to modify it was made)
-     * 
-     * <p>
-     * Use {@link PropertyModifyEvent#getProposed()} to determine whether the
-     * property was being set or cleared.
-     * 
-     * @param ev
-     */
-    void propertyModified(PropertyModifyEvent ev);
-
-    /**
-     * A check was made to determine if a collection was visible.
-     * 
-     * <p>
-     * Will be fired prior to
-     * {@link #collectionUsable(CollectionUsabilityEvent)}.
-     * 
-     * @param ev
-     */
-    void collectionVisible(CollectionVisibilityEvent ev);
-
-    /**
-     * A check was made to determine if a collection was usable.
-     * 
-     * <p>
-     * Will be fired prior to either
-     * {@link #collectionAccessed(CollectionAccessEvent)} or
-     * {@link #collectionAddedTo(CollectionAddToEvent)} or
-     * {@link #collectionRemovedFrom(CollectionRemoveFromEvent)}.
-     * 
-     * @param ev
-     */
-    void collectionUsable(CollectionUsabilityEvent ev);
-
-    /**
-     * A collection was read.
-     * 
-     * <p>
-     * Unlike most other events, a {@link CollectionAccessEvent} will never have
-     * been vetoed (that is, {@link CollectionAccessEvent#isVeto()} will always
-     * be <tt>false</tt>).
-     * 
-     * @param ev
-     */
-    void collectionAccessed(CollectionAccessEvent ev);
-
-    /**
-     * An object was added to the collection (or an attempt to add it was made).
-     * 
-     * @param ev
-     */
-    void collectionAddedTo(CollectionAddToEvent ev);
-
-    /**
-     * An object was removed from the collection (or an attempt to remove it was
-     * made).
-     * 
-     * @param ev
-     */
-    void collectionRemovedFrom(CollectionRemoveFromEvent ev);
-
-/**
-     * A method of a collection (such as <tt>isEmpty()</tt> or <tt>size()</tt>) has been invoked.
-     * 
-     * 
-     * <p>
-     * Unlike the other methods in this interface, the source of these events will be an instance of a
-     * Collection (such as <tt>java.util.List</tt>) rather than the domain object. (The domain object is
-     * {@link CollectionMethodEvent#getDomainObject() still available,  however).
-     * 
-     * @param interactionEvent
-     */
-    void collectionMethodInvoked(CollectionMethodEvent interactionEvent);
-
-    /**
-     * A check was made to determine if an action was visible.
-     * 
-     * <p>
-     * Will be fired prior to {@link #actionUsable(ActionUsabilityEvent)}.
-     * 
-     * @param ev
-     */
-    void actionVisible(ActionVisibilityEvent interactionEvent);
-
-    /**
-     * A check was made to determine if an action was usable.
-     * 
-     * <p>
-     * Will be fired prior to {@link #actionArgument(ActionArgumentEvent)}.
-     * 
-     * @param ev
-     */
-    void actionUsable(ActionUsabilityEvent ev);
-
-    /**
-     * A check was made as to whether an argument proposed for an action was
-     * valid.
-     * 
-     * <p>
-     * Will be fired prior to {@link #actionInvoked(ActionInvocationEvent)}.
-     * 
-     * @param ev
-     */
-    void actionArgument(ActionArgumentEvent ev);
-
-    /**
-     * An action was invoked (or an attempt to invoke it was made).
-     * 
-     * @param ev
-     */
-    void actionInvoked(ActionInvocationEvent ev);
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/site/apt/index.apt b/component/progmodel/wrapper/wrapper-applib/src/site/apt/index.apt
deleted file mode 100644
index ae48c91..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/site/apt/index.apt
+++ /dev/null
@@ -1,24 +0,0 @@
-~~  Licensed to the Apache Software Foundation (ASF) under one
-~~  or more contributor license agreements.  See the NOTICE file
-~~  distributed with this work for additional information
-~~  regarding copyright ownership.  The ASF licenses this file
-~~  to you under the Apache License, Version 2.0 (the
-~~  "License"); you may not use this file except in compliance
-~~  with the License.  You may obtain a copy of the License at
-~~
-~~        http://www.apache.org/licenses/LICENSE-2.0
-~~
-~~  Unless required by applicable law or agreed to in writing,
-~~  software distributed under the License is distributed on an
-~~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-~~  KIND, either express or implied.  See the License for the
-~~  specific language governing permissions and limitations
-~~  under the License.
-
-
-
-Headless AppLib
- 
- The <headless applib> decouples the domain objects from the <headless> viewer implementation.  Its main 
- responsibility is to define the <<<HeadlessViewer>>> interface, by which the domain object proxies are obtained.
- It also defines the exceptions that are raised to indicate invalid interactions between domain objects.

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/site/apt/jottings.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/site/apt/jottings.apt b/component/progmodel/wrapper/wrapper-applib/src/site/apt/jottings.apt
deleted file mode 100644
index c5d1200..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/site/apt/jottings.apt
+++ /dev/null
@@ -1,24 +0,0 @@
-~~  Licensed to the Apache Software Foundation (ASF) under one
-~~  or more contributor license agreements.  See the NOTICE file
-~~  distributed with this work for additional information
-~~  regarding copyright ownership.  The ASF licenses this file
-~~  to you under the Apache License, Version 2.0 (the
-~~  "License"); you may not use this file except in compliance
-~~  with the License.  You may obtain a copy of the License at
-~~
-~~        http://www.apache.org/licenses/LICENSE-2.0
-~~
-~~  Unless required by applicable law or agreed to in writing,
-~~  software distributed under the License is distributed on an
-~~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-~~  KIND, either express or implied.  See the License for the
-~~  specific language governing permissions and limitations
-~~  under the License.
-
-
-
-Jottings
- 
-  This page is to capture any random jottings relating to this module prior 
-  to being moved into formal documentation. 
- 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-applib/src/site/site.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-applib/src/site/site.xml b/component/progmodel/wrapper/wrapper-applib/src/site/site.xml
deleted file mode 100644
index 692a6a3..0000000
--- a/component/progmodel/wrapper/wrapper-applib/src/site/site.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project>
-
-	<body>
-		<breadcrumbs>
-			<item name="Applib" href="index.html"/>
-		</breadcrumbs>
-
-		<menu name="Wrapper Applib">
-			<item name="About" href="index.html" />
-            <item name="Jottings" href="jottings.html" />
-		</menu>
-
-        <menu name="Wrapper Modules">
-            <item name="Applib" href="../wrapper-applib/index.html" />
-            <item name="Metamodel" href="../wrapper-metamodel/index.html" />
-        </menu>
-
-        <menu name="Maven Reports" ref="reports" />
-	</body>
-</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/pom.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/pom.xml b/component/progmodel/wrapper/wrapper-metamodel/pom.xml
deleted file mode 100644
index 48bd674..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/pom.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.isis.progmodel</groupId>
-        <artifactId>isis-progmodel-wrapper</artifactId>
-        <version>1.0.0-SNAPSHOT</version>
-	</parent>
-
-	<artifactId>isis-progmodel-wrapper-metamodel</artifactId>
-
-	<name>Isis Wrapper ProgModel MetaModel</name>
-	<description>Isis Wrapper Programming Model Metamodel Support</description>
-
-
-	<properties>
-        <siteBaseDir>..</siteBaseDir>
-		<relativeUrl>wrapper-metamodel/</relativeUrl>
-	</properties>
-
-    <!-- used in Site generation for relative references. -->
-    <url>http://isis.apache.org/${relativeUrl}</url>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-project-info-reports-plugin</artifactId>
-				<version>${maven-project-info-reports-plugin}</version>
-                <inherited>false</inherited>
-                <configuration>
-                	<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
-                </configuration>
-                <reportSets>
-                    <reportSet>
-                        <inherited>false</inherited>
-                        <reports>
-                            <report>dependencies</report>
-                            <report>dependency-convergence</report>
-                            <report>plugins</report>
-                            <report>summary</report>
-                        </reports>
-                    </reportSet>
-                </reportSets>
-            </plugin>
-        </plugins>
-    </reporting>
-
-	<dependencies>
-		<dependency>
-            <groupId>org.apache.isis.progmodel</groupId>
-			<artifactId>isis-progmodel-wrapper-applib</artifactId>
-        </dependency>
-
-        <dependency>
-		    <groupId>org.apache.isis.core</groupId>
-		    <artifactId>isis-core-runtime</artifactId>
-        </dependency>
-
-		<dependency>
-		    <groupId>org.apache.isis.core</groupId>
-		    <artifactId>isis-core-metamodel</artifactId>
-		    <type>test-jar</type>
-		    <scope>test</scope>
-        </dependency>
-		<dependency>
-		    <groupId>org.apache.isis.core</groupId>
-		    <artifactId>isis-core-runtime</artifactId>
-		    <type>test-jar</type>
-		    <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core-unittestsupport</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core-tck-dom</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-		<dependency>
-            <groupId>asm</groupId>
-            <artifactId>asm</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>org.objenesis</groupId>
-			<artifactId>objenesis</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>cglib</groupId>
-			<artifactId>cglib-nodep</artifactId>
-		</dependency>
-
-
-	</dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
deleted file mode 100644
index a5f09e8..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/DomainObjectContainerWrapperFactory.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel;
-
-import java.util.List;
-
-import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
-import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
-import org.apache.isis.progmodel.wrapper.applib.listeners.InteractionListener;
-import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
-
-/**
- * A combined {@link DomainObjectContainer} and {@link WrapperFactory}.
- */
-public class DomainObjectContainerWrapperFactory extends DomainObjectContainerDefault implements WrapperFactory {
-
-    private final WrapperFactoryDefault wrapperFactoryDelegate;
-
-    public DomainObjectContainerWrapperFactory() {
-        this.wrapperFactoryDelegate = new WrapperFactoryDefault();
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Views
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public <T> T wrap(final T domainObject) {
-        return wrapperFactoryDelegate.wrap(domainObject);
-    }
-
-    @Override
-    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
-        return wrapperFactoryDelegate.wrap(domainObject, mode);
-    }
-
-    @Override
-    public boolean isWrapper(final Object possibleView) {
-        return wrapperFactoryDelegate.isWrapper(possibleView);
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Listeners
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public List<InteractionListener> getListeners() {
-        return wrapperFactoryDelegate.getListeners();
-    }
-
-    @Override
-    public boolean addInteractionListener(final InteractionListener listener) {
-        return wrapperFactoryDelegate.addInteractionListener(listener);
-    }
-
-    @Override
-    public boolean removeInteractionListener(final InteractionListener listener) {
-        return wrapperFactoryDelegate.removeInteractionListener(listener);
-    }
-
-    @Override
-    public void notifyListeners(final InteractionEvent interactionEvent) {
-        wrapperFactoryDelegate.notifyListeners(interactionEvent);
-    }
-
-    // /////////////////////////////////////////////////////////////
-    // Dependencies
-    // /////////////////////////////////////////////////////////////
-
-    @Override
-    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
-        super.setSpecificationLookup(specificationLookup);
-        wrapperFactoryDelegate.setSpecificationLookup(specificationLookup);
-    }
-
-    @Override
-    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
-        super.setAuthenticationSessionProvider(authenticationSessionProvider);
-        wrapperFactoryDelegate.setAuthenticationSessionProvider(authenticationSessionProvider);
-    }
-
-    @Override
-    public void setAdapterManager(final AdapterManager adapterManager) {
-        super.setAdapterManager(adapterManager);
-        wrapperFactoryDelegate.setAdapterManager(adapterManager);
-    }
-
-    @Override
-    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
-        super.setObjectPersistor(objectPersistor);
-        wrapperFactoryDelegate.setObjectPersistor(objectPersistor);
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
deleted file mode 100644
index 75e5fce..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/AbstractCollectionInvocationHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.isis.applib.events.CollectionMethodEvent;
-import org.apache.isis.applib.events.InteractionEvent;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-abstract class AbstractCollectionInvocationHandler<T, C> extends DelegatingInvocationHandlerDefault<C> {
-
-    private final List<Method> interceptedMethods = new ArrayList<Method>();
-    private final List<Method> vetoedMethods = new ArrayList<Method>();
-    private final String collectionName;
-    private final OneToManyAssociation oneToManyAssociation;
-    private final T domainObject;
-
-    public AbstractCollectionInvocationHandler(final C collectionOrMapToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionOrMapToProxy, handler.getHeadlessViewer(), handler.getExecutionMode());
-        this.collectionName = collectionName;
-        this.oneToManyAssociation = otma;
-        this.domainObject = handler.getDelegate();
-    }
-
-    protected Method intercept(final Method method) {
-        this.interceptedMethods.add(method);
-        return method;
-    }
-
-    protected Method veto(final Method method) {
-        this.vetoedMethods.add(method);
-        return method;
-    }
-
-    public String getCollectionName() {
-        return collectionName;
-    }
-
-    public OneToManyAssociation getCollection() {
-        return oneToManyAssociation;
-    }
-
-    public T getDomainObject() {
-        return domainObject;
-    }
-
-    @Override
-    public Object invoke(final Object collectionObject, final Method method, final Object[] args) throws Throwable {
-
-        // delegate
-        final Object returnValueObj = delegate(method, args);
-
-        if (interceptedMethods.contains(method)) {
-
-            resolveIfRequired(domainObject);
-
-            final InteractionEvent ev = new CollectionMethodEvent(getDelegate(), getCollection().getIdentifier(), getDomainObject(), method.getName(), args, returnValueObj);
-            notifyListeners(ev);
-            return returnValueObj;
-        }
-
-        if (vetoedMethods.contains(method)) {
-            throw new UnsupportedOperationException(String.format("Method '%s' may not be called directly.", method.getName()));
-        }
-
-        return returnValueObj;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
deleted file mode 100644
index aaa2ae0..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibClassProxyFactory.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.lang.reflect.InvocationHandler;
-
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.MethodInterceptor;
-
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
-
-/**
- * Factory generating a mock for a class.
- * <p>
- * Note that this class is stateful
- */
-public class CgLibClassProxyFactory<T> implements IProxyFactory<T> {
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final T toProxy, final InvocationHandler handler) {
-        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
-        return createProxy(proxyClass, handler);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T createProxy(final Class<T> toProxyClass, final InvocationHandler handler) {
-
-        final MethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
-
-        // Create the proxy
-        final Enhancer enhancer = new Enhancer();
-        enhancer.setSuperclass(toProxyClass);
-        enhancer.setInterfaces(new Class[] { WrapperObject.class });
-        enhancer.setCallbackType(interceptor.getClass());
-
-        final Class<?> enhancedClass = enhancer.createClass();
-
-        Enhancer.registerCallbacks(enhancedClass, new Callback[] { interceptor });
-
-        Factory factory;
-        try {
-            factory = (Factory) ClassInstantiatorFactoryCE.getInstantiator().newInstance(enhancedClass);
-        } catch (final InstantiationException e) {
-            throw new RuntimeException("Fail to instantiate mock for " + toProxyClass + " on " + ClassInstantiatorFactoryCE.getJVM() + " JVM");
-        }
-
-        return (T) factory;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
deleted file mode 100644
index f931d23..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CgLibProxy.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-
-import org.apache.isis.core.metamodel.specloader.classsubstitutor.CglibEnhanced;
-import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
-
-public class CgLibProxy<T> {
-
-    private final DelegatingInvocationHandler<T> handler;
-
-    public CgLibProxy(final DelegatingInvocationHandler<T> handler) {
-        this.handler = handler;
-    }
-
-    @SuppressWarnings("unchecked")
-    public T proxy() {
-
-        final T toProxy = handler.getDelegate();
-
-        // handle if already proxied using cglib.
-        if (CglibEnhanced.class.isAssignableFrom(toProxy.getClass())) {
-
-            handler.setResolveObjectChangedEnabled(true);
-
-            final Class<? extends Object> enhancedClass = toProxy.getClass();
-            final Class<? extends Object> origSuperclass = toProxy.getClass().getSuperclass();
-
-            final List<Class> interfaces = new ArrayList<Class>();
-            interfaces.addAll(Arrays.asList(enhancedClass.getInterfaces()));
-            interfaces.remove(Factory.class); // if there.
-            interfaces.add(WrapperObject.class);
-
-            InvocationHandlerMethodInterceptor interceptor = new InvocationHandlerMethodInterceptor(handler);
-            return (T) Enhancer.create(origSuperclass, interfaces.toArray(new Class[] {}), interceptor);
-        }
-
-        final Class<T> clazz = (Class<T>) toProxy.getClass();
-
-        T proxy = null;
-        try {
-            final IProxyFactory<T> proxyFactory = clazz.isInterface() ? new JavaProxyFactory<T>() : new CgLibClassProxyFactory<T>();
-            proxy = proxyFactory.createProxy(clazz, handler);
-        } catch (final RuntimeExceptionWrapper e) {
-            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
-        }
-        return proxy;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
deleted file mode 100644
index 85bc196..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ClassInstantiatorFactoryCE.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-/**
- * Factory returning a {@link IClassInstantiatorCE}for the current JVM
- */
-class ClassInstantiatorFactoryCE {
-
-    private static IClassInstantiatorCE instantiator = new ObjenesisClassInstantiatorCE();
-
-    // ///CLOVER:OFF
-    private ClassInstantiatorFactoryCE() {
-    }
-
-    // ///CLOVER:ON
-
-    /**
-     * Returns the current JVM as specified in the Systtem properties
-     * 
-     * @return current JVM
-     */
-    public static String getJVM() {
-        return System.getProperty("java.vm.vendor");
-    }
-
-    /**
-     * Returns the current JVM specification version (1.5, 1.4, 1.3)
-     * 
-     * @return current JVM specification version
-     */
-    public static String getJVMSpecificationVersion() {
-        return System.getProperty("java.specification.version");
-    }
-
-    public static boolean is1_3Specifications() {
-        return getJVMSpecificationVersion().equals("1.3");
-    }
-
-    /**
-     * Returns a class instantiator suitable for the current JVM
-     * 
-     * @return a class instantiator usable on the current JVM
-     */
-    public static IClassInstantiatorCE getInstantiator() {
-        return instantiator;
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
deleted file mode 100644
index d143af6..0000000
--- a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/CollectionInvocationHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.progmodel.wrapper.metamodel.internal;
-
-import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-class CollectionInvocationHandler<T, R> extends AbstractCollectionInvocationHandler<T, R> {
-
-    public CollectionInvocationHandler(final R collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-        super(collectionToProxy, collectionName, handler, otma);
-
-        try {
-            intercept(getMethod(collectionToProxy, "contains", Object.class));
-            intercept(getMethod(collectionToProxy, "size"));
-            intercept(getMethod(collectionToProxy, "isEmpty"));
-            if (collectionToProxy instanceof List) {
-                intercept(getMethod(collectionToProxy, "get", int.class));
-            }
-            veto(getMethod(collectionToProxy, "add", Object.class));
-            veto(getMethod(collectionToProxy, "remove", Object.class));
-            veto(getMethod(collectionToProxy, "addAll", Collection.class));
-            veto(getMethod(collectionToProxy, "removeAll", Collection.class));
-            veto(getMethod(collectionToProxy, "retainAll", Collection.class));
-            veto(getMethod(collectionToProxy, "clear"));
-        } catch (final NoSuchMethodException e) {
-            // ///CLOVER:OFF
-            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
-            // ///CLOVER:ON
-        }
-    }
-
-}


[2/8] ISIS-409: moving wrapper progmodel into core, as a service

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
new file mode 100644
index 0000000..93121ff
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DelegatingInvocationHandlerDefault.java
@@ -0,0 +1,131 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerObjectChanged;
+import org.apache.isis.core.runtime.persistence.container.DomainObjectContainerResolve;
+
+public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocationHandler<T> {
+
+    private final T delegate;
+    protected final WrapperFactory wrapperFactory;
+    private final ExecutionMode executionMode;
+
+    protected final Method equalsMethod;
+    protected final Method hashCodeMethod;
+    protected final Method toStringMethod;
+
+    private final DomainObjectContainerObjectChanged domainObjectContainerObjectChanged;
+    private final DomainObjectContainerResolve domainObjectContainerResolve;
+
+    private boolean resolveObjectChangedEnabled;
+
+    public DelegatingInvocationHandlerDefault(final T delegate, final WrapperFactory headlessViewer, final ExecutionMode executionMode) {
+        if (delegate == null) {
+            throw new IllegalArgumentException("delegate must not be null");
+        }
+        this.delegate = delegate;
+        this.wrapperFactory = headlessViewer;
+        this.executionMode = executionMode;
+
+        this.domainObjectContainerResolve = new DomainObjectContainerResolve();
+        this.domainObjectContainerObjectChanged = new DomainObjectContainerObjectChanged();
+
+        try {
+            equalsMethod = delegate.getClass().getMethod("equals", new Class[] { Object.class });
+            hashCodeMethod = delegate.getClass().getMethod("hashCode", new Class[] {});
+            toStringMethod = delegate.getClass().getMethod("toString", new Class[] {});
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("An Object method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+    @Override
+    public boolean isResolveObjectChangedEnabled() {
+        return resolveObjectChangedEnabled;
+    }
+
+    @Override
+    public void setResolveObjectChangedEnabled(final boolean resolveObjectChangedEnabled) {
+        this.resolveObjectChangedEnabled = resolveObjectChangedEnabled;
+    }
+
+    protected void resolveIfRequired(final ObjectAdapter targetAdapter) {
+        resolveIfRequired(targetAdapter.getObject());
+    }
+
+    protected void resolveIfRequired(final Object domainObject) {
+        if (resolveObjectChangedEnabled) {
+            domainObjectContainerResolve.resolve(domainObject);
+        }
+    }
+
+    protected void objectChangedIfRequired(final ObjectAdapter targetAdapter) {
+        objectChangedIfRequired(targetAdapter.getObject());
+    }
+
+    protected void objectChangedIfRequired(final Object domainObject) {
+        if (resolveObjectChangedEnabled) {
+            domainObjectContainerObjectChanged.objectChanged(domainObject);
+        }
+    }
+
+    public WrapperFactory getHeadlessViewer() {
+        return wrapperFactory;
+    }
+
+    @Override
+    public T getDelegate() {
+        return delegate;
+    }
+
+    public ExecutionMode getExecutionMode() {
+        return executionMode;
+    }
+
+    protected Object delegate(final Method method, final Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+
+        return method.invoke(getDelegate(), args);
+    }
+
+    protected boolean isObjectMethod(final Method method) {
+        return toStringMethod.equals(method) || hashCodeMethod.equals(method) || equalsMethod.equals(method);
+    }
+
+    @Override
+    public Object invoke(final Object object, final Method method, final Object[] args) throws Throwable {
+        return method.invoke(object, args);
+    }
+
+    protected InteractionEvent notifyListeners(final InteractionEvent interactionEvent) {
+        wrapperFactory.notifyListeners(interactionEvent);
+        return interactionEvent;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
new file mode 100644
index 0000000..66ce9eb
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/DomainObjectInvocationHandler.java
@@ -0,0 +1,645 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.UsabilityEvent;
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.applib.events.VisibilityEvent;
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.services.wrapper.DisabledException;
+import org.apache.isis.applib.services.wrapper.HiddenException;
+import org.apache.isis.applib.services.wrapper.InteractionException;
+import org.apache.isis.applib.services.wrapper.InvalidException;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
+import org.apache.isis.core.metamodel.consent.InteractionResult;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.accessor.PropertyOrCollectionAccessorFacet;
+import org.apache.isis.core.metamodel.facets.actions.choices.ActionChoicesFacet;
+import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertyInitializationFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
+import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
+import org.apache.isis.core.progmodel.facets.actions.validate.method.ActionValidationFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateRemoveFromFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.members.disabled.method.DisableForContextFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.members.hidden.method.HideForContextFacetViaMethod;
+import org.apache.isis.core.progmodel.facets.properties.modify.PropertyClearFacetViaClearMethod;
+import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaModifyMethod;
+import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacetViaMethod;
+
+public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandlerDefault<T> {
+
+    private final Map<Method, Collection<?>> collectionViewObjectsByMethod = new HashMap<Method, Collection<?>>();
+    private final Map<Method, Map<?, ?>> mapViewObjectsByMethod = new HashMap<Method, Map<?, ?>>();
+
+    private final AuthenticationSessionProvider authenticationSessionProvider;
+    private final SpecificationLoader specificationLookup;
+    private final AdapterManager adapterManager;
+    private final ObjectPersistor objectPersistor;
+
+    /**
+     * The <tt>title()</tt> method; may be <tt>null</tt>.
+     */
+    protected Method titleMethod;
+
+    /**
+     * The <tt>save()</tt> method from {@link WrapperObject#save()}.
+     */
+    protected Method saveMethod;
+
+    /**
+     * The <tt>underlying()</tt> method from {@link WrapperObject#wrapped()}.
+     */
+    protected Method wrappedMethod;
+
+    public DomainObjectInvocationHandler(final T delegate, final WrapperFactory embeddedViewer, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager,
+            final ObjectPersistor objectPersistor) {
+        super(delegate, embeddedViewer, mode);
+
+        this.authenticationSessionProvider = authenticationSessionProvider;
+        this.specificationLookup = specificationLookup;
+        this.adapterManager = adapterManager;
+        this.objectPersistor = objectPersistor;
+
+        try {
+            titleMethod = delegate.getClass().getMethod("title", new Class[] {});
+            saveMethod = WrapperObject.class.getMethod("save", new Class[] {});
+            wrappedMethod = WrapperObject.class.getMethod("wrapped", new Class[] {});
+        } catch (final NoSuchMethodException e) {
+        }
+    }
+
+    @Override
+    public Object invoke(final Object proxyObject, final Method method, final Object[] args) throws Throwable {
+
+        if (isObjectMethod(method)) {
+            return delegate(method, args);
+        }
+
+        final ObjectAdapter targetAdapter = getAdapterManager().getAdapterFor(getDelegate());
+
+        if (isTitleMethod(method)) {
+            return handleTitleMethod(method, args, targetAdapter);
+        }
+
+        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
+
+        // save method, through the proxy
+        if (isSaveMethod(method)) {
+            return handleSaveMethod(getAuthenticationSession(), targetAdapter, targetNoSpec);
+        }
+
+        if (isUnderlyingMethod(method)) {
+            return getDelegate();
+        }
+
+        final ObjectMember objectMember = locateAndCheckMember(method);
+        final List<Facet> imperativeFacets = getImperativeFacets(objectMember, method);
+
+        final String memberName = objectMember.getName();
+
+        if (instanceOf(imperativeFacets, DisableForContextFacetViaMethod.class, HideForContextFacetViaMethod.class)) {
+            throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'", memberName));
+        }
+
+        final String methodName = method.getName();
+
+        if (instanceOf(imperativeFacets, ActionDefaultsFacet.class, PropertyDefaultFacet.class, ActionChoicesFacet.class, ActionParameterChoicesFacet.class, PropertyChoicesFacet.class)) {
+            return method.invoke(getDelegate(), args);
+        }
+
+        // for all members, check visibility and usability
+        checkVisibility(getAuthenticationSession(), targetAdapter, objectMember);
+
+        if (objectMember.isOneToOneAssociation()) {
+
+            if (instanceOf(imperativeFacets, PropertyValidateFacetViaMethod.class, PropertySetterFacetViaModifyMethod.class, PropertyClearFacetViaClearMethod.class)) {
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only property accessor/mutator", memberName));
+            }
+
+            final OneToOneAssociation otoa = (OneToOneAssociation) objectMember;
+            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
+                return handleGetterMethodOnProperty(args, targetAdapter, otoa, methodName);
+            }
+            if (instanceOf(imperativeFacets, PropertySetterFacet.class, PropertyInitializationFacet.class)) {
+                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+                return handleSetterMethodOnProperty(args, getAuthenticationSession(), targetAdapter, otoa, methodName);
+            }
+        }
+        if (objectMember.isOneToManyAssociation()) {
+
+            if (instanceOf(imperativeFacets, CollectionValidateAddToFacetViaMethod.class, CollectionValidateRemoveFromFacetViaMethod.class)) {
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only collection accessor/mutator", memberName));
+            }
+
+            final OneToManyAssociation otma = (OneToManyAssociation) objectMember;
+            if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
+                return handleGetterMethodOnCollection(method, args, targetAdapter, otma, memberName);
+            }
+            if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
+                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+                return handleCollectionAddToMethod(args, targetAdapter, otma, methodName);
+            }
+            if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
+                checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+                return handleCollectionRemoveFromMethod(args, targetAdapter, otma, methodName);
+            }
+        }
+
+        // filter out
+        if (instanceOf(imperativeFacets, PropertyOrCollectionAccessorFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke accessor on properties or collections; '%s' represents %s", methodName, decode(objectMember)));
+        }
+        if (instanceOf(imperativeFacets, PropertySetterFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke mutator on properties; '%s' represents %s", methodName, decode(objectMember)));
+        }
+        if (instanceOf(imperativeFacets, CollectionAddToFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke 'adder' on collections; '%s' represents %s", methodName, decode(objectMember)));
+        }
+        if (instanceOf(imperativeFacets, CollectionRemoveFromFacet.class)) {
+            throw new UnsupportedOperationException(String.format("Can only invoke 'remover' on collections; '%s' represents %s", methodName, decode(objectMember)));
+        }
+
+        if (objectMember instanceof ObjectAction) {
+
+            if (instanceOf(imperativeFacets, ActionValidationFacetViaMethod.class)) {
+                throw new UnsupportedOperationException(String.format("Cannot invoke supporting method '%s'; use only the 'invoke' method", memberName));
+            }
+
+            checkUsability(getAuthenticationSession(), targetAdapter, objectMember);
+
+            final ObjectAction noa = (ObjectAction) objectMember;
+            return handleActionMethod(args, getAuthenticationSession(), targetAdapter, noa, memberName);
+        }
+
+        throw new UnsupportedOperationException(String.format("Unknown member type '%s'", objectMember));
+    }
+
+    public List<Facet> getImperativeFacets(final ObjectMember objectMember, final Method method) {
+        final List<Facet> imperativeFacets = objectMember.getFacets(new Filter<Facet>() {
+            @Override
+            public boolean accept(final Facet facet) {
+                final ImperativeFacet imperativeFacet = asImperativeFacet(facet);
+                if (imperativeFacet == null) {
+                    return false;
+                }
+                return imperativeFacet.getMethods().contains(method);
+            }
+
+            private ImperativeFacet asImperativeFacet(final Facet facet) {
+                if (facet == null) {
+                    return null;
+                }
+                if (facet instanceof ImperativeFacet) {
+                    return (ImperativeFacet) facet;
+                }
+                return asImperativeFacet(facet.getUnderlyingFacet());
+            }
+        });
+
+        // there will be at least one
+        if (imperativeFacets.isEmpty()) {
+            throw new IllegalStateException("should be at least one imperative facet");
+        }
+        return imperativeFacets;
+    }
+
+    private static boolean instanceOf(final List<?> objects, final Class<?>... superTypes) {
+        for (final Class<?> superType : superTypes) {
+            for (final Object obj : objects) {
+                if (superType.isAssignableFrom(obj.getClass())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // title
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleTitleMethod(final Method method, final Object[] args, final ObjectAdapter targetAdapter) throws IllegalAccessException, InvocationTargetException {
+
+        resolveIfRequired(targetAdapter);
+
+        final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
+        final ObjectTitleContext titleContext = targetNoSpec.createTitleInteractionContext(getAuthenticationSession(), InteractionInvocationMethod.BY_USER, targetAdapter);
+        final ObjectTitleEvent titleEvent = titleContext.createInteractionEvent();
+        notifyListeners(titleEvent);
+        return titleEvent.getTitle();
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // save
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleSaveMethod(final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectSpecification targetNoSpec) {
+
+        final InteractionResult interactionResult = targetNoSpec.isValidResult(targetAdapter);
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            if (targetAdapter.isTransient()) {
+                getObjectPersistor().makePersistent(targetAdapter);
+            }
+        }
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // property - access
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleGetterMethodOnProperty(final Object[] args, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
+        if (args.length != 0) {
+            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final ObjectAdapter currentReferencedAdapter = otoa.get(targetAdapter);
+        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
+
+        final PropertyAccessEvent ev = new PropertyAccessEvent(getDelegate(), otoa.getIdentifier(), currentReferencedObj);
+        notifyListeners(ev);
+        return currentReferencedObj;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // property - modify
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleSetterMethodOnProperty(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final OneToOneAssociation otoa, final String methodName) {
+        if (args.length != 1) {
+            throw new IllegalArgumentException("Invoking a setter should only have a single argument");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final Object argumentObj = underlying(args[0]);
+        final ObjectAdapter argumentAdapter = argumentObj != null ? getAdapterManager().adapterFor(argumentObj) : null;
+
+        final InteractionResult interactionResult = otoa.isAssociationValid(targetAdapter, argumentAdapter).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            otoa.set(targetAdapter, argumentAdapter);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // collection - access
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleGetterMethodOnCollection(final Method method, final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String memberName) {
+        if (args.length != 0) {
+            throw new IllegalArgumentException("Invoking a 'get' should have no arguments");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final ObjectAdapter currentReferencedAdapter = otma.get(targetAdapter);
+        final Object currentReferencedObj = AdapterUtils.unwrap(currentReferencedAdapter);
+
+        final CollectionAccessEvent ev = new CollectionAccessEvent(getDelegate(), otma.getIdentifier());
+
+        if (currentReferencedObj instanceof Collection) {
+            final Collection<?> collectionViewObject = lookupViewObject(method, memberName, (Collection<?>) currentReferencedObj, otma);
+            notifyListeners(ev);
+            return collectionViewObject;
+        } else if (currentReferencedObj instanceof Map) {
+            final Map<?, ?> mapViewObject = lookupViewObject(method, memberName, (Map<?, ?>) currentReferencedObj, otma);
+            notifyListeners(ev);
+            return mapViewObject;
+        }
+        throw new IllegalArgumentException(String.format("Collection type '%s' not supported by framework", currentReferencedObj.getClass().getName()));
+    }
+
+    /**
+     * Looks up (or creates) a proxy for this object.
+     */
+    private Collection<?> lookupViewObject(final Method method, final String memberName, final Collection<?> collectionToLookup, final OneToManyAssociation otma) {
+        Collection<?> collectionViewObject = collectionViewObjectsByMethod.get(method);
+        if (collectionViewObject == null) {
+            if (collectionToLookup instanceof WrapperObject) {
+                collectionViewObject = collectionToLookup;
+            } else {
+                collectionViewObject = Proxy.proxy(collectionToLookup, memberName, this, otma);
+            }
+            collectionViewObjectsByMethod.put(method, collectionViewObject);
+        }
+        return collectionViewObject;
+    }
+
+    private Map<?, ?> lookupViewObject(final Method method, final String memberName, final Map<?, ?> mapToLookup, final OneToManyAssociation otma) {
+        Map<?, ?> mapViewObject = mapViewObjectsByMethod.get(method);
+        if (mapViewObject == null) {
+            if (mapToLookup instanceof WrapperObject) {
+                mapViewObject = mapToLookup;
+            } else {
+                mapViewObject = Proxy.proxy(mapToLookup, memberName, this, otma);
+            }
+            mapViewObjectsByMethod.put(method, mapViewObject);
+        }
+        return mapViewObject;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // collection - add to
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleCollectionAddToMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
+
+        if (args.length != 1) {
+            throw new IllegalArgumentException("Invoking a addTo should only have a single argument");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final Object argumentObj = underlying(args[0]);
+        if (argumentObj == null) {
+            throw new IllegalArgumentException("Must provide a non-null object to add");
+        }
+        final ObjectAdapter argumentNO = getAdapterManager().adapterFor(argumentObj);
+
+        final InteractionResult interactionResult = otma.isValidToAdd(targetAdapter, argumentNO).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            otma.addElement(targetAdapter, argumentNO);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // collection - remove from
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleCollectionRemoveFromMethod(final Object[] args, final ObjectAdapter targetAdapter, final OneToManyAssociation otma, final String methodName) {
+        if (args.length != 1) {
+            throw new IllegalArgumentException("Invoking a removeFrom should only have a single argument");
+        }
+
+        resolveIfRequired(targetAdapter);
+
+        final Object argumentObj = underlying(args[0]);
+        if (argumentObj == null) {
+            throw new IllegalArgumentException("Must provide a non-null object to remove");
+        }
+        final ObjectAdapter argumentAdapter = getAdapterManager().adapterFor(argumentObj);
+
+        final InteractionResult interactionResult = otma.isValidToRemove(targetAdapter, argumentAdapter).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            otma.removeElement(targetAdapter, argumentAdapter);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // action
+    // /////////////////////////////////////////////////////////////////
+
+    private Object handleActionMethod(final Object[] args, final AuthenticationSession session, final ObjectAdapter targetAdapter, final ObjectAction noa, final String memberName) {
+
+        final Object[] underlyingArgs = new Object[args.length];
+        int i = 0;
+        for (final Object arg : args) {
+            underlyingArgs[i++] = underlying(arg);
+        }
+
+        final ObjectAdapter[] argAdapters = new ObjectAdapter[underlyingArgs.length];
+        int j = 0;
+        for (final Object underlyingArg : underlyingArgs) {
+            argAdapters[j++] = underlyingArg != null ? getAdapterManager().adapterFor(underlyingArg) : null;
+        }
+
+        final InteractionResult interactionResult = noa.isProposedArgumentSetValid(targetAdapter, argAdapters).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+
+        if (getExecutionMode() == ExecutionMode.EXECUTE) {
+            final ObjectAdapter actionReturnNO = noa.execute(targetAdapter, argAdapters);
+            return AdapterUtils.unwrap(actionReturnNO);
+        }
+
+        objectChangedIfRequired(targetAdapter);
+
+        return null;
+    }
+
+    private Object underlying(final Object arg) {
+        if (arg instanceof WrapperObject) {
+            final WrapperObject argViewObject = (WrapperObject) arg;
+            return argViewObject.wrapped();
+        } else {
+            return arg;
+        }
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // visibility and usability checks (common to all members)
+    // /////////////////////////////////////////////////////////////////
+
+    /**
+     * REVIEW: ideally should provide some way to allow to caller to indicate the 'where' context.  Having
+     * a hard-coded value like this is an approximation. 
+     */
+    private final Where where = Where.ANYWHERE;
+
+    private void checkVisibility(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
+        final Consent visibleConsent = objectMember.isVisible(getAuthenticationSession(), targetObjectAdapter, where);
+        final InteractionResult interactionResult = visibleConsent.getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+    }
+
+    private void checkUsability(final AuthenticationSession session, final ObjectAdapter targetObjectAdapter, final ObjectMember objectMember) {
+        final InteractionResult interactionResult = objectMember.isUsable(getAuthenticationSession(), targetObjectAdapter, where).getInteractionResult();
+        notifyListenersAndVetoIfRequired(interactionResult);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // notify listeners
+    // /////////////////////////////////////////////////////////////////
+
+    private void notifyListenersAndVetoIfRequired(final InteractionResult interactionResult) {
+        final InteractionEvent interactionEvent = interactionResult.getInteractionEvent();
+        notifyListeners(interactionEvent);
+        if (interactionEvent.isVeto()) {
+            throw toException(interactionEvent);
+        }
+    }
+
+    private String decode(final ObjectMember objectMember) {
+        if (objectMember instanceof OneToOneAssociation) {
+            return "a property";
+        }
+        if (objectMember instanceof OneToManyAssociation) {
+            return "a collection";
+        }
+        if (objectMember instanceof ObjectAction) {
+            return "an action";
+        }
+        return "an UNKNOWN member type";
+    }
+
+    /**
+     * Wraps a {@link InteractionEvent#isVeto() vetoing}
+     * {@link InteractionEvent} in a corresponding {@link InteractionException},
+     * and returns it.
+     */
+    private InteractionException toException(final InteractionEvent interactionEvent) {
+        if (!interactionEvent.isVeto()) {
+            throw new IllegalArgumentException("Provided interactionEvent must be a veto");
+        }
+        if (interactionEvent instanceof ValidityEvent) {
+            final ValidityEvent validityEvent = (ValidityEvent) interactionEvent;
+            return new InvalidException(validityEvent);
+        }
+        if (interactionEvent instanceof VisibilityEvent) {
+            final VisibilityEvent visibilityEvent = (VisibilityEvent) interactionEvent;
+            return new HiddenException(visibilityEvent);
+        }
+        if (interactionEvent instanceof UsabilityEvent) {
+            final UsabilityEvent usabilityEvent = (UsabilityEvent) interactionEvent;
+            return new DisabledException(usabilityEvent);
+        }
+        throw new IllegalArgumentException("Provided interactionEvent must be a VisibilityEvent, UsabilityEvent or a ValidityEvent");
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // switching
+    // /////////////////////////////////////////////////////////////////
+
+    private ObjectMember locateAndCheckMember(final Method method) {
+        final ObjectSpecificationDefault objectSpecificationDefault = getJavaSpecificationOfOwningClass(method);
+        final ObjectMember member = objectSpecificationDefault.getMember(method);
+        if (member == null) {
+            final String methodName = method.getName();
+            throw new UnsupportedOperationException("Method '" + methodName + "' being invoked does not correspond to any of the object's fields or actions.");
+        }
+        return member;
+    }
+
+    protected boolean isTitleMethod(final Method method) {
+        return method.equals(titleMethod);
+    }
+
+    protected boolean isSaveMethod(final Method method) {
+        return method.equals(saveMethod);
+    }
+
+    protected boolean isUnderlyingMethod(final Method method) {
+        return method.equals(wrappedMethod);
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Specification lookup
+    // /////////////////////////////////////////////////////////////////
+
+    private ObjectSpecificationDefault getJavaSpecificationOfOwningClass(final Method method) {
+        return getJavaSpecification(method.getDeclaringClass());
+    }
+
+    private ObjectSpecificationDefault getJavaSpecification(final Class<?> clazz) {
+        final ObjectSpecification nos = getSpecification(clazz);
+        if (!(nos instanceof ObjectSpecificationDefault)) {
+            throw new UnsupportedOperationException("Only Java is supported (specification is '" + nos.getClass().getCanonicalName() + "')");
+        }
+        return (ObjectSpecificationDefault) nos;
+    }
+
+    private ObjectSpecification getSpecification(final Class<?> type) {
+        final ObjectSpecification nos = getSpecificationLookup().loadSpecification(type);
+        return nos;
+    }
+
+    // /////////////////////////////////////////////////////////////////
+    // Dependencies
+    // /////////////////////////////////////////////////////////////////
+
+    protected SpecificationLoader getSpecificationLookup() {
+        return specificationLookup;
+    }
+
+    public AuthenticationSessionProvider getAuthenticationSessionProvider() {
+        return authenticationSessionProvider;
+    }
+
+    protected AuthenticationSession getAuthenticationSession() {
+        return getAuthenticationSessionProvider().getAuthenticationSession();
+    }
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+    protected ObjectPersistor getObjectPersistor() {
+        return objectPersistor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
new file mode 100644
index 0000000..d551c72
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IClassInstantiatorCE.java
@@ -0,0 +1,37 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+/**
+ * Used to instantiate a given class.
+ */
+interface IClassInstantiatorCE {
+
+    /**
+     * Return a new instance of the specified class. The recommended way is
+     * without calling any constructor. This is usually done by doing like
+     * <code>ObjectInputStream.readObject()</code> which is JVM specific.
+     * 
+     * @param c
+     *            Class to instantiate
+     * @return new instance of clazz
+     */
+    Object newInstance(Class<?> clazz) throws InstantiationException;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
new file mode 100644
index 0000000..c92c0e8
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
@@ -0,0 +1,28 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+public interface IProxyFactory<T> {
+    T createProxy(Class<T> toProxyClass, InvocationHandler handler);
+
+    T createProxy(T toProxy, InvocationHandler handler);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
new file mode 100644
index 0000000..0515501
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
@@ -0,0 +1,28 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import org.apache.isis.applib.events.InteractionEvent;
+
+public interface InteractionEventDispatcher {
+
+    void dispatch(InteractionEvent interactionEvent);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
new file mode 100644
index 0000000..5ae80f6
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
@@ -0,0 +1,34 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import org.apache.isis.applib.events.InteractionEvent;
+
+public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> implements InteractionEventDispatcher {
+
+    public abstract void dispatchTypeSafe(T interactionEvent);
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void dispatch(final InteractionEvent interactionEvent) {
+        dispatchTypeSafe((T) interactionEvent);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
new file mode 100644
index 0000000..ebdcb52
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+public class InvocationHandlerMethodInterceptor implements MethodInterceptor {
+    private final InvocationHandler handler;
+
+    InvocationHandlerMethodInterceptor(final InvocationHandler handler) {
+        this.handler = handler;
+    }
+
+    @Override
+    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
+        return handler.invoke(obj, method, args);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
new file mode 100644
index 0000000..e67a31d
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+
+public class JavaProxyFactory<T> implements IProxyFactory<T> {
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final T toProxy, final InvocationHandler handler) {
+        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
+        return (T) Proxy.newProxyInstance(proxyClass.getClassLoader(), new Class[] { proxyClass }, handler);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final Class<T> toProxy, final InvocationHandler handler) {
+        return (T) Proxy.newProxyInstance(toProxy.getClassLoader(), new Class[] { toProxy, WrapperObject.class }, handler);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
new file mode 100644
index 0000000..779afac
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
@@ -0,0 +1,49 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
+
+import java.util.Map;
+
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+class MapInvocationHandler<T, C> extends AbstractCollectionInvocationHandler<T, C> {
+
+    public MapInvocationHandler(final C collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionToProxy, collectionName, handler, otma);
+
+        try {
+            intercept(getMethod(collectionToProxy, "containsKey", Object.class));
+            intercept(getMethod(collectionToProxy, "containsValue", Object.class));
+            intercept(getMethod(collectionToProxy, "size"));
+            intercept(getMethod(collectionToProxy, "isEmpty"));
+            veto(getMethod(collectionToProxy, "put", Object.class, Object.class));
+            veto(getMethod(collectionToProxy, "remove", Object.class));
+            veto(getMethod(collectionToProxy, "putAll", Map.class));
+            veto(getMethod(collectionToProxy, "clear"));
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
new file mode 100644
index 0000000..00028f1
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.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.progmodel.wrapper.metamodel.internal;
+
+import org.objenesis.ObjenesisHelper;
+
+class ObjenesisClassInstantiatorCE implements IClassInstantiatorCE {
+
+    @Override
+    public Object newInstance(final Class<?> clazz) throws InstantiationException {
+        return ObjenesisHelper.newInstance(clazz);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
new file mode 100644
index 0000000..5008c2f
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
@@ -0,0 +1,80 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.ensure.Ensure;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+public class Proxy {
+
+    public static <T> T proxy(final T domainObject, final WrapperFactory wrapperFactory, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager, final ObjectPersistor objectPersistor) {
+
+        Ensure.ensureThatArg(wrapperFactory, is(not(nullValue())));
+        Ensure.ensureThatArg(authenticationSessionProvider, is(not(nullValue())));
+        Ensure.ensureThatArg(specificationLookup, is(not(nullValue())));
+        Ensure.ensureThatArg(adapterManager, is(not(nullValue())));
+        Ensure.ensureThatArg(objectPersistor, is(not(nullValue())));
+
+        final DomainObjectInvocationHandler<T> invocationHandler = new DomainObjectInvocationHandler<T>(domainObject, wrapperFactory, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
+
+        final CgLibProxy<T> cglibProxy = new CgLibProxy<T>(invocationHandler);
+        return cglibProxy.proxy();
+    }
+
+    /**
+     * Whether to execute or not will be picked up from the supplied parent
+     * handler.
+     */
+    public static <T, E> Collection<E> proxy(final Collection<E> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+
+        final CollectionInvocationHandler<T, Collection<E>> collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(collectionToProxy, collectionName, handler, otma);
+        collectionInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+
+        final CgLibProxy<Collection<E>> cglibProxy = new CgLibProxy<Collection<E>>(collectionInvocationHandler);
+        return cglibProxy.proxy();
+    }
+
+    /**
+     * Whether to execute or not will be picked up from the supplied parent
+     * handler.
+     */
+    public static <T, P, Q> Map<P, Q> proxy(final Map<P, Q> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+
+        final MapInvocationHandler<T, Map<P, Q>> mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(collectionToProxy, collectionName, handler, otma);
+        mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+
+        final CgLibProxy<Map<P, Q>> cglibProxy = new CgLibProxy<Map<P, Q>>(mapInvocationHandler);
+        return cglibProxy.proxy();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
new file mode 100644
index 0000000..b6eae03
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
@@ -0,0 +1,33 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+public class RuntimeExceptionWrapper extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private final RuntimeException runtimeException;
+
+    public RuntimeExceptionWrapper(final RuntimeException runtimeException) {
+        this.runtimeException = runtimeException;
+    }
+
+    public RuntimeException getRuntimeException() {
+        return runtimeException;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
new file mode 100644
index 0000000..4a51a03
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
@@ -0,0 +1,271 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.events.ActionArgumentEvent;
+import org.apache.isis.applib.events.ActionInvocationEvent;
+import org.apache.isis.applib.events.ActionUsabilityEvent;
+import org.apache.isis.applib.events.ActionVisibilityEvent;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.CollectionAddToEvent;
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.CollectionRemoveFromEvent;
+import org.apache.isis.applib.events.CollectionUsabilityEvent;
+import org.apache.isis.applib.events.CollectionVisibilityEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.ObjectValidityEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrapperObject;
+import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistorAware;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
+
+public class WrapperFactoryDefault implements WrapperFactory, AuthenticationSessionProviderAware, SpecificationLoaderAware, AdapterManagerAware, ObjectPersistorAware {
+
+    private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
+    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> dispatchersByEventClass = new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
+
+    private AuthenticationSessionProvider authenticationSessionProvider;
+    private SpecificationLoader specificationLookup;
+    private AdapterManager adapterManager;
+    private ObjectPersistor objectPersistor;
+
+    public WrapperFactoryDefault() {
+        dispatchersByEventClass.put(ObjectTitleEvent.class, new InteractionEventDispatcherTypeSafe<ObjectTitleEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ObjectTitleEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.objectTitleRead(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyAccessEvent.class, new InteractionEventDispatcherTypeSafe<PropertyAccessEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyAccessEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyAccessed(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyModifyEvent.class, new InteractionEventDispatcherTypeSafe<PropertyModifyEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyModifyEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyModified(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionAccessEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAccessEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionAccessEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionAccessed(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionAddToEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAddToEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionAddToEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionAddedTo(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionRemoveFromEvent.class, new InteractionEventDispatcherTypeSafe<CollectionRemoveFromEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionRemoveFromEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionRemovedFrom(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionArgumentEvent.class, new InteractionEventDispatcherTypeSafe<ActionArgumentEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionArgumentEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionArgument(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionInvocationEvent.class, new InteractionEventDispatcherTypeSafe<ActionInvocationEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionInvocationEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionInvoked(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ObjectValidityEvent.class, new InteractionEventDispatcherTypeSafe<ObjectValidityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ObjectValidityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.objectPersisted(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionMethodEvent.class, new InteractionEventDispatcherTypeSafe<CollectionMethodEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionMethodEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionMethodInvoked(interactionEvent);
+                }
+            }
+        });
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Views
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public <T> T wrap(final T domainObject) {
+        return wrap(domainObject, ExecutionMode.EXECUTE);
+    }
+
+    @Override
+    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
+        if (isWrapper(domainObject)) {
+            return domainObject;
+        }
+        return Proxy.proxy(domainObject, this, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
+    }
+
+    @Override
+    public boolean isWrapper(final Object possibleWrapper) {
+        return possibleWrapper instanceof WrapperObject;
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public List<InteractionListener> getListeners() {
+        return listeners;
+    }
+
+    @Override
+    public boolean addInteractionListener(final InteractionListener listener) {
+        return listeners.add(listener);
+    }
+
+    @Override
+    public boolean removeInteractionListener(final InteractionListener listener) {
+        return listeners.remove(listener);
+    }
+
+    @Override
+    public void notifyListeners(final InteractionEvent interactionEvent) {
+        final InteractionEventDispatcher dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
+        if (dispatcher == null) {
+            throw new RuntimeException("Unknown InteractionEvent - register into dispatchers map");
+        }
+        dispatcher.dispatch(interactionEvent);
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
+        this.authenticationSessionProvider = authenticationSessionProvider;
+    }
+
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    @Override
+    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
+        this.specificationLookup = specificationLookup;
+    }
+
+    @Override
+    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
+        this.objectPersistor = objectPersistor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
new file mode 100644
index 0000000..2b743c5
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
@@ -0,0 +1,52 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal.util;
+
+public final class Constants {
+    private Constants() {
+    }
+
+    public static final String PREFIX_CHOICES = "choices";
+    public static final String PREFIX_DEFAULT = "default";
+    public static final String PREFIX_HIDE = "hide";
+    public static final String PREFIX_DISABLE = "disable";
+    public static final String PREFIX_VALIDATE_REMOVE_FROM = "validateRemoveFrom";
+    public static final String PREFIX_VALIDATE_ADD_TO = "validateAddTo";
+    public static final String PREFIX_VALIDATE = "validate";
+    public static final String PREFIX_REMOVE_FROM = "removeFrom";
+    public static final String PREFIX_ADD_TO = "addTo";
+    public static final String PREFIX_MODIFY = "modify";
+    public static final String PREFIX_CLEAR = "clear";
+    public static final String PREFIX_SET = "set";
+    public static final String PREFIX_GET = "get";
+
+    public final static String TITLE_METHOD_NAME = "title";
+    public final static String TO_STRING_METHOD_NAME = "toString";
+
+    /**
+     * Cannot invoke methods with these prefixes.
+     */
+    public final static String[] INVALID_PREFIXES = { PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, };
+
+    public final static String[] PROPERTY_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
+    public final static String[] COLLECTION_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_ADD_TO, PREFIX_REMOVE_FROM, PREFIX_DISABLE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
+    public final static String[] ACTION_PREFIXES = { PREFIX_VALIDATE, PREFIX_DISABLE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES, };
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
----------------------------------------------------------------------
diff --git a/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
new file mode 100644
index 0000000..b2de21c
--- /dev/null
+++ b/core/wrapper/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
@@ -0,0 +1,48 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal.util;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+
+public final class MethodPrefixFinder {
+
+    // a Linked Hash Set is used to ensure that the ordering is preserved.
+    public final static LinkedHashSet<String> ALL_PREFIXES = new LinkedHashSet<String>() {
+        private static final long serialVersionUID = 1L;
+        {
+            // collection prefixes are added first because we want to
+            // test validateAddTo and validateRemoveFrom before validate
+            addAll(Arrays.asList(Constants.COLLECTION_PREFIXES));
+            addAll(Arrays.asList(Constants.PROPERTY_PREFIXES));
+            addAll(Arrays.asList(Constants.ACTION_PREFIXES));
+        }
+    };
+
+    public String findPrefix(final String methodName) {
+        for (final String prefix : ALL_PREFIXES) {
+            if (methodName.startsWith(prefix)) {
+                return prefix;
+            }
+        }
+        return "";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/core/wrapper/src/site/apt/index.apt b/core/wrapper/src/site/apt/index.apt
new file mode 100644
index 0000000..1a1f4fa
--- /dev/null
+++ b/core/wrapper/src/site/apt/index.apt
@@ -0,0 +1,22 @@
+~~  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.
+
+
+
+Headless Viewer
+ 
+ The <headless viewer> module provides the main implementation of the headless viewer functionality.

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/site/apt/jottings.apt
----------------------------------------------------------------------
diff --git a/core/wrapper/src/site/apt/jottings.apt b/core/wrapper/src/site/apt/jottings.apt
new file mode 100644
index 0000000..c5d1200
--- /dev/null
+++ b/core/wrapper/src/site/apt/jottings.apt
@@ -0,0 +1,24 @@
+~~  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.
+
+
+
+Jottings
+ 
+  This page is to capture any random jottings relating to this module prior 
+  to being moved into formal documentation. 
+ 

http://git-wip-us.apache.org/repos/asf/isis/blob/cd0735d2/core/wrapper/src/site/site.xml
----------------------------------------------------------------------
diff --git a/core/wrapper/src/site/site.xml b/core/wrapper/src/site/site.xml
new file mode 100644
index 0000000..6def7c8
--- /dev/null
+++ b/core/wrapper/src/site/site.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project>
+
+	<body>
+		<breadcrumbs>
+			<item name="Metamodel" href="index.html" />
+		</breadcrumbs>
+
+		<menu name="Wrapper Metamodel">
+			<item name="About" href="index.html" />
+            <item name="Jottings" href="jottings.html" />
+		</menu>
+
+        <menu name="Wrapper Modules">
+            <item name="Applib" href="../wrapper-applib/index.html" />
+            <item name="Metamodel" href="../wrapper-metamodel/index.html" />
+        </menu>
+
+        <menu name="Maven Reports" ref="reports" />
+	</body>
+</project>