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 2015/09/03 14:32:39 UTC

[48/87] [abbrv] [partial] isis git commit: ISIS-1194: moving the wicket submodules to be direct children of core; removing the isis-viewer-wicket parent pom.

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java
new file mode 100644
index 0000000..6121101
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java
@@ -0,0 +1,78 @@
+/*
+ *  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.wicket.viewer;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassList;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistrarDefault;
+import org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistryDefault;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassRegistryDefault;
+
+@RunWith(Parameterized.class)
+public class WicketObjectModule_bindingsStandard {
+
+    private IsisWicketModule wicketObjectsModule;
+    private Injector injector;
+    private final Class<?> from;
+    private final Class<?> to;
+
+    @Parameters
+    public static Collection<Object[]> params() {
+        return Arrays.asList(new Object[][] { { ComponentFactoryRegistrar.class, ComponentFactoryRegistrarDefault.class }, { ComponentFactoryRegistry.class, ComponentFactoryRegistryDefault.class }, { PageClassList.class, PageClassListDefault.class },
+                { PageClassRegistry.class, PageClassRegistryDefault.class }, });
+    }
+
+    public WicketObjectModule_bindingsStandard(final Class<?> from, final Class<?> to) {
+        this.from = from;
+        this.to = to;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        wicketObjectsModule = new IsisWicketModule();
+        injector = Guice.createInjector(wicketObjectsModule);
+    }
+
+    @Test
+    public void binding() {
+        final Object instance = injector.getInstance(from);
+        assertThat(instance, is(instanceOf(to)));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java
new file mode 100644
index 0000000..2ecd81c
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.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.viewer.wicket.viewer.app.wicket;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import java.util.Locale;
+
+import org.apache.wicket.request.Request;
+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.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis;
+
+public class AuthenticatedWebSessionForIsis_Authenticate {
+
+    @Rule
+    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    private AuthenticatedWebSessionForIsis webSession;
+    @Mock
+    private Request stubRequest;
+    @Mock
+    private AuthenticationManager mockAuthMgr;
+
+    @Before
+    public void setUp() throws Exception {
+        context.checking(new Expectations() {
+            {
+                // must provide explicit expectation, since Locale is final.
+                allowing(stubRequest).getLocale();
+                will(returnValue(Locale.getDefault()));
+
+                // stub everything else out
+                ignoring(stubRequest);
+            }
+        });
+
+    }
+
+    @Test
+    public void delegatesToAuthenticationManagerAndCachesAuthSessionIfOk() {
+
+        context.checking(new Expectations() {
+            {
+                one(mockAuthMgr).authenticate(with(any(AuthenticationRequest.class)));
+            }
+        });
+
+        webSession = new AuthenticatedWebSessionForIsis(stubRequest) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected AuthenticationManager getAuthenticationManager() {
+                return mockAuthMgr;
+            }
+        };
+        assertThat(webSession.authenticate("jsmith", "secret"), is(true));
+        assertThat(webSession.getAuthenticationSession(), is(not(nullValue())));
+    }
+
+    @Test
+    public void delegatesToAuthenticationManagerAndHandlesIfNotAuthenticated() {
+        context.checking(new Expectations() {
+            {
+                one(mockAuthMgr).authenticate(with(any(AuthenticationRequest.class)));
+                will(returnValue(null));
+            }
+        });
+        webSession = new AuthenticatedWebSessionForIsis(stubRequest) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected AuthenticationManager getAuthenticationManager() {
+                return mockAuthMgr;
+            }
+        };
+        assertThat(webSession.authenticate("jsmith", "secret"), is(false));
+        assertThat(webSession.getAuthenticationSession(), is(nullValue()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_DownCastsInheritedFunctionality.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_DownCastsInheritedFunctionality.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_DownCastsInheritedFunctionality.java
new file mode 100644
index 0000000..7d5b133
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_DownCastsInheritedFunctionality.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.viewer.wicket.viewer.app.wicket;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class AuthenticatedWebSessionForIsis_DownCastsInheritedFunctionality {
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @Ignore("thread-safe downcast of inherited functionality")
+    @Test
+    public void testGet() {
+    }
+
+    @Ignore("thread-safe downcast of inherited functionality")
+    @Test
+    public void testGetClientInfo() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Instantiation.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Instantiation.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Instantiation.java
new file mode 100644
index 0000000..4f5c860
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Instantiation.java
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.wicket.viewer.app.wicket;
+
+import java.util.Locale;
+
+import org.apache.wicket.request.Request;
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis;
+
+public class AuthenticatedWebSessionForIsis_Instantiation {
+
+    @Rule
+    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private Request stubRequest;
+
+    @Test
+    public void canInstantiateIfProvideRequest() {
+        context.checking(new Expectations() {
+            {
+                // must provide explicit expectation, since Locale is final.
+                allowing(stubRequest).getLocale();
+                will(returnValue(Locale.getDefault()));
+
+                // stub everything else out
+                ignoring(stubRequest);
+            }
+        });
+
+        new AuthenticatedWebSessionForIsis(stubRequest);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void requestMustBeProvided() {
+        new AuthenticatedWebSessionForIsis(null);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_NotYetImplemented.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_NotYetImplemented.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_NotYetImplemented.java
new file mode 100644
index 0000000..8c4f56b
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_NotYetImplemented.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.viewer.wicket.viewer.app.wicket;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class AuthenticatedWebSessionForIsis_NotYetImplemented {
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @Ignore("not yet implemented")
+    @Test
+    public void testIsDebugMode() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_SignIn.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_SignIn.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_SignIn.java
new file mode 100644
index 0000000..a06abe4
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_SignIn.java
@@ -0,0 +1,85 @@
+/*
+ *  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.wicket.viewer.app.wicket;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Locale;
+
+import org.apache.wicket.request.Request;
+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.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis;
+
+public class AuthenticatedWebSessionForIsis_SignIn {
+
+    @Rule
+    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    private AuthenticatedWebSessionForIsis webSession;
+    @Mock
+    private Request stubRequest;
+    @Mock
+    private AuthenticationManager mockAuthMgr;
+
+    @Before
+    public void setUp() throws Exception {
+        context.checking(new Expectations() {
+            {
+                // must provide explicit expectation, since Locale is final.
+                allowing(stubRequest).getLocale();
+                will(returnValue(Locale.getDefault()));
+
+                // stub everything else out
+                ignoring(stubRequest);
+            }
+        });
+
+    }
+
+    @Test
+    public void signInJustDelegatesToAuthenticateAndSavesState() {
+        context.checking(new Expectations() {
+            {
+                one(mockAuthMgr).authenticate(with(any(AuthenticationRequest.class)));
+            }
+        });
+
+        webSession = new AuthenticatedWebSessionForIsis(stubRequest) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected AuthenticationManager getAuthenticationManager() {
+                return mockAuthMgr;
+            }
+        };
+        webSession.signIn("john", "secret");
+        assertThat(webSession.isSignedIn(), is(true));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/imagecache/ImageResourceCacheKeyTest.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/imagecache/ImageResourceCacheKeyTest.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/imagecache/ImageResourceCacheKeyTest.java
new file mode 100644
index 0000000..90c95e6
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/imagecache/ImageResourceCacheKeyTest.java
@@ -0,0 +1,219 @@
+/*
+ *  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.wicket.viewer.imagecache;
+
+import java.util.Iterator;
+import java.util.List;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class ImageResourceCacheKeyTest {
+
+    ImageResourceCacheKey key;
+
+    public static class SomeSuperclass {
+    }
+
+    public static class SomeSubclass extends SomeSuperclass {
+    }
+
+    public static class SomeOtherContextClass extends SomeSuperclass {
+    }
+
+
+    public static class SuperKey extends ImageResourceCacheKeyTest {
+
+        @Test
+        public void whenSubclass() throws Exception {
+
+            key = new ImageResourceCacheKey(SomeSubclass.class, "foo");
+            final ImageResourceCacheKey superKey = key.superKey();
+
+            assertEquals(SomeSuperclass.class, superKey.getResourceClass());
+            assertEquals("foo", key.getResourceName());
+        }
+
+        @Test
+        public void whenSuperClass() throws Exception {
+
+            key = new ImageResourceCacheKey(SomeSuperclass.class, null);
+            final ImageResourceCacheKey superKey = key.superKey();
+
+            assertNull(superKey);
+        }
+
+    }
+
+    public static class ResourcePaths extends ImageResourceCacheKeyTest {
+
+        @Test
+        public void withIconName() throws Exception {
+            key = new ImageResourceCacheKey(SomeSubclass.class, "foo");
+
+            final List<ImageResourceCacheKey> keys = key.resourcePaths("png", "jpg", "jpeg");
+
+            final Iterator<ImageResourceCacheKey> iterator = keys.iterator();
+
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass-foo.png");
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass-foo.jpg");
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass-foo.jpeg");
+
+            assertNext(iterator, SomeSubclass.class, "foo.png");
+            assertNext(iterator, SomeSubclass.class, "foo.jpg");
+            assertNext(iterator, SomeSubclass.class, "foo.jpeg");
+
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass-foo.png");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass-foo.jpg");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass-foo.jpeg");
+
+            assertNext(iterator, SomeSuperclass.class, "foo.png");
+            assertNext(iterator, SomeSuperclass.class, "foo.jpg");
+            assertNext(iterator, SomeSuperclass.class, "foo.jpeg");
+
+            assertNext(iterator, null, "SomeSubclass-foo.png");
+            assertNext(iterator, null, "SomeSubclass-foo.jpg");
+            assertNext(iterator, null, "SomeSubclass-foo.jpeg");
+
+            assertNext(iterator, null, "SomeSuperclass-foo.png");
+            assertNext(iterator, null, "SomeSuperclass-foo.jpg");
+            assertNext(iterator, null, "SomeSuperclass-foo.jpeg");
+
+            assertNext(iterator, null, "foo.png");
+            assertNext(iterator, null, "foo.jpg");
+            assertNext(iterator, null, "foo.jpeg");
+
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass.png");
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass.jpg");
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass.jpeg");
+
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.png");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpg");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpeg");
+
+            assertNext(iterator, null, "SomeSubclass.png");
+            assertNext(iterator, null, "SomeSubclass.jpg");
+            assertNext(iterator, null, "SomeSubclass.jpeg");
+
+            assertNext(iterator, null, "SomeSuperclass.png");
+            assertNext(iterator, null, "SomeSuperclass.jpg");
+            assertNext(iterator, null, "SomeSuperclass.jpeg");
+
+            assertNext(iterator, null, "Default.png");
+            assertNext(iterator, null, "Default.jpg");
+            assertNext(iterator, null, "Default.jpeg");
+
+        }
+
+        @Test
+        public void withoutIconName() throws Exception {
+            key = new ImageResourceCacheKey(SomeSubclass.class, null);
+
+            final List<ImageResourceCacheKey> keys = key.resourcePaths("png", "jpg", "jpeg");
+
+            final Iterator<ImageResourceCacheKey> iterator = keys.iterator();
+
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass.png");
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass.jpg");
+            assertNext(iterator, SomeSubclass.class, "SomeSubclass.jpeg");
+
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.png");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpg");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpeg");
+
+            assertNext(iterator, null, "SomeSubclass.png");
+            assertNext(iterator, null, "SomeSubclass.jpg");
+            assertNext(iterator, null, "SomeSubclass.jpeg");
+
+            assertNext(iterator, null, "SomeSuperclass.png");
+            assertNext(iterator, null, "SomeSuperclass.jpg");
+            assertNext(iterator, null, "SomeSuperclass.jpeg");
+
+            assertNext(iterator, null, "Default.png");
+            assertNext(iterator, null, "Default.jpg");
+            assertNext(iterator, null, "Default.jpeg");
+
+        }
+
+        @Test
+        public void withoutClass() throws Exception {
+            key = new ImageResourceCacheKey(null, "foo");
+
+            final List<ImageResourceCacheKey> keys = key.resourcePaths("png", "jpg", "jpeg");
+
+            final Iterator<ImageResourceCacheKey> iterator = keys.iterator();
+
+            assertNext(iterator, null, "foo.png");
+            assertNext(iterator, null, "foo.jpg");
+            assertNext(iterator, null, "foo.jpeg");
+
+            assertNext(iterator, null, "Default.png");
+            assertNext(iterator, null, "Default.jpg");
+            assertNext(iterator, null, "Default.jpeg");
+        }
+
+        /**
+         * This what we see for repositories (using <code></code>@DomainService(repositoryFor=...))
+         */
+        @Test
+        public void withoutClassButIconNameSpecifyingADifferentContextClassAndClassName() throws Exception {
+            key = new ImageResourceCacheKey(SomeOtherContextClass.class, SomeSuperclass.class.getName());
+
+            final List<ImageResourceCacheKey> keys = key.resourcePaths("png", "jpg", "jpeg");
+
+            final Iterator<ImageResourceCacheKey> iterator = keys.iterator();
+
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.png");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpg");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpeg");
+
+            assertNext(iterator, null, "Default.png");
+            assertNext(iterator, null, "Default.jpg");
+            assertNext(iterator, null, "Default.jpeg");
+
+        }
+
+        @Test
+        public void withoutClassButIconNameSpecifyingAClassName() throws Exception {
+            key = new ImageResourceCacheKey(null, SomeSuperclass.class.getName());
+
+            final List<ImageResourceCacheKey> keys = key.resourcePaths("png", "jpg", "jpeg");
+
+            final Iterator<ImageResourceCacheKey> iterator = keys.iterator();
+
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.png");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpg");
+            assertNext(iterator, SomeSuperclass.class, "SomeSuperclass.jpeg");
+
+            assertNext(iterator, null, "Default.png");
+            assertNext(iterator, null, "Default.jpg");
+            assertNext(iterator, null, "Default.jpeg");
+
+        }
+
+        private static void assertNext(Iterator<ImageResourceCacheKey> iterator, Class<?> resourceClass, String resourceName) {
+            assertThat(iterator.hasNext(), is(true));
+            final ImageResourceCacheKey next = iterator.next();
+            assertEquals(resourceClass, next.getResourceClass());
+            assertEquals(resourceName, next.getResourceName());
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_Instantiation.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_Instantiation.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_Instantiation.java
new file mode 100644
index 0000000..4861d62
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_Instantiation.java
@@ -0,0 +1,69 @@
+/*
+ *  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.wicket.viewer.pages;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.isis.viewer.wicket.ui.pages.PageClassList;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistrySpi;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassRegistryDefault;
+
+@RunWith(JMock.class)
+public class PageClassListDefault_Instantiation {
+
+    private final Mockery context = new JUnit4Mockery();
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void shouldCauseAllPagesToBeRegistered() {
+        // necessary to provide an implementation that will register
+        // all pages with the registry.
+        final PageClassListDefault pageClassList = new PageClassListDefault();
+        new PageClassRegistryDefault(pageClassList);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void shouldFailIfNoPagesRegistered() {
+        // no side effects, ie doesn't register
+        final PageClassList mockPageClassList = context.mock(PageClassList.class);
+        context.checking(new Expectations() {
+            {
+                mockPageClassList.registerPages(with(any(PageClassRegistrySpi.class)));
+            }
+        });
+        new PageClassRegistryDefault(mockPageClassList);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_RegistrationAndCaching.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_RegistrationAndCaching.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_RegistrationAndCaching.java
new file mode 100644
index 0000000..b482435
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/pages/PageClassListDefault_RegistrationAndCaching.java
@@ -0,0 +1,68 @@
+/*
+ *  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.wicket.viewer.pages;
+
+import org.apache.wicket.Page;
+import org.junit.Before;
+import org.junit.Test;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.actionprompt.ActionPromptPage;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault;
+import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassRegistryDefault;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class PageClassListDefault_RegistrationAndCaching {
+
+    private PageClassRegistryDefault registryImpl;
+
+    @Before
+    public void setUp() throws Exception {
+        // necessary to provide an implementation that will register
+        // all pages with the registry.
+        final PageClassListDefault pageClassList = new PageClassListDefault();
+        registryImpl = new PageClassRegistryDefault(pageClassList);
+    }
+
+    @Test
+    public void cachesPageByPageType() {
+        final Class<? extends Page> pageClass = registryImpl.getPageClass(PageType.ACTION_PROMPT);
+        assertThat(pageClass, is(not(nullValue())));
+    }
+
+    @Test
+    public void canRegisterNewPageType() {
+        class TestingActionPage extends ActionPromptPage {
+            TestingActionPage() {
+                super((ActionModel) null);
+            }
+        }
+        registryImpl.registerPage(PageType.ACTION_PROMPT, TestingActionPage.class);
+
+        final Class<? extends Page> pageClass = registryImpl.getPageClass(PageType.ACTION_PROMPT);
+        assertThat(pageClass, is(instanceOf(TestingActionPage.class)));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicketTest.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicketTest.java b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicketTest.java
new file mode 100644
index 0000000..1027a93
--- /dev/null
+++ b/core/viewer-wicket-impl/src/test/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicketTest.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.wicket.viewer.services;
+
+import java.io.File;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeThat;
+
+public class TranslationsResolverWicketTest {
+
+    public static class NewFile extends TranslationsResolverWicketTest {
+
+        @Before
+        public void setUp() throws Exception {
+            assumeThat(System.getProperty("os.name").startsWith("Windows"), is(true));
+        }
+
+        @Test
+        public void simple() throws Exception {
+            final File file = TranslationsResolverWicket.newFile("c:/foo", "bar");
+            final String absolutePath = file.getAbsolutePath();
+            assertThat(absolutePath, is("c:\\foo\\bar"));
+        }
+
+        @Test
+        public void nestedChild() throws Exception {
+            final File file = TranslationsResolverWicket.newFile("c:/foo", "bar/baz");
+            final String absolutePath = file.getAbsolutePath();
+            assertThat(absolutePath, is("c:\\foo\\bar\\baz"));
+        }
+
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/pom.xml
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/pom.xml b/core/viewer-wicket-model/pom.xml
new file mode 100644
index 0000000..d6d19fa
--- /dev/null
+++ b/core/viewer-wicket-model/pom.xml
@@ -0,0 +1,76 @@
+<?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/xsd/maven-4.0.0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.isis.core</groupId>
+		<artifactId>isis</artifactId>
+		<version>1.10.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>isis-viewer-wicket-model</artifactId>
+	<name>Isis Wicket Viewer Model</name>
+
+	<properties>
+		<siteBaseDir>..</siteBaseDir>
+		<relativeUrl>model/</relativeUrl>
+	</properties>
+
+    <!-- used in Site generation for relative references. -->
+    <url>http://isis.apache.org/${relativeUrl}</url>
+
+	<dependencies>
+
+        <dependency>
+            <groupId>org.apache.isis.viewer</groupId>
+            <artifactId>isis-viewer-wicket-applib</artifactId>
+        </dependency>
+
+		<dependency>
+			<groupId>org.apache.wicket</groupId>
+			<artifactId>wicket-core</artifactId>
+		</dependency>
+        <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket-extensions</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>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.isis.core</groupId>
+			<artifactId>isis-core-unittestsupport</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+	</dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java
new file mode 100644
index 0000000..71b1e71
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.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.viewer.wicket.model.common;
+
+import java.io.Serializable;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
+
+/**
+ * Decouples the handling of concurrency exceptions when a bulk action is invoked (between the toggle box column and the
+ * standalone collection panel).
+ */
+public interface OnConcurrencyExceptionHandler extends Serializable {
+
+    void onConcurrencyException(
+            Component context, ObjectAdapter selectedAdapter,
+            ConcurrencyException ex,
+            AjaxRequestTarget ajaxRequestTarget);
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
new file mode 100644
index 0000000..491c144
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.wicket.model.common;
+
+import java.io.Serializable;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+
+/**
+ * Decouples the selecting of items (by a toggle box column) from the invocation of bulk actions on those items (by
+ * the standalone collection panel).
+ */
+public interface OnSelectionHandler extends Serializable {
+
+    void onSelected(
+            Component context, ObjectAdapter selectedAdapter,
+            AjaxRequestTarget ajaxRequestTarget);
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/PageParametersUtils.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/PageParametersUtils.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/PageParametersUtils.java
new file mode 100644
index 0000000..8d4e0b1
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/common/PageParametersUtils.java
@@ -0,0 +1,70 @@
+/*
+ *  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.wicket.model.common;
+
+import org.apache.wicket.core.request.handler.IPageRequestHandler;
+import org.apache.wicket.request.cycle.PageRequestHandlerTracker;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.util.string.StringValue;
+
+/**
+ * A helper class for dealing with PageParameters
+ */
+public class PageParametersUtils {
+
+    /**
+     * The name of the special request parameter that controls whether the page header/navigation bar
+     * should be shown or not
+     */
+    public static final String ISIS_NO_HEADER_PARAMETER_NAME = "isis.no.header";
+
+    /**
+     * The name of the special request parameter that controls whether the page footer
+     * should be shown or not
+     */
+    public static final String ISIS_NO_FOOTER_PARAMETER_NAME = "isis.no.footer";
+
+    /**
+     * Creates a new instance of PageParameters that preserves some special request parameters
+     * which should propagate in all links created by Isis
+     *
+     * @return a new PageParameters instance
+     */
+    public static PageParameters newPageParameters() {
+        final PageParameters newPageParameters = new PageParameters();
+        final RequestCycle cycle = RequestCycle.get();
+
+        if (cycle != null) {
+            final IPageRequestHandler pageRequestHandler = PageRequestHandlerTracker.getFirstHandler(cycle);
+            final PageParameters currentPageParameters = pageRequestHandler.getPageParameters();
+            if (currentPageParameters != null) {
+                final StringValue noHeader = currentPageParameters.get(ISIS_NO_HEADER_PARAMETER_NAME);
+                if (!noHeader.isNull()) {
+                    newPageParameters.set(ISIS_NO_HEADER_PARAMETER_NAME, noHeader.toString());
+                }
+                final StringValue noFooter = currentPageParameters.get(ISIS_NO_FOOTER_PARAMETER_NAME);
+                if (!noFooter.isNull()) {
+                    newPageParameters.set(ISIS_NO_FOOTER_PARAMETER_NAME, noFooter.toString());
+                }
+            }
+        }
+        return newPageParameters;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisActionCompletedEvent.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisActionCompletedEvent.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisActionCompletedEvent.java
new file mode 100644
index 0000000..e020070
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisActionCompletedEvent.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.viewer.wicket.model.hints;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+
+/**
+ *
+ */
+public class IsisActionCompletedEvent extends IsisEventLetterAbstract {
+
+    private final ActionModel actionModel;
+    private final Form<?> form;
+
+    public IsisActionCompletedEvent(ActionModel actionModel, AjaxRequestTarget target, Form<?> form) {
+        super(target);
+        this.actionModel = actionModel;
+        this.form = form;
+    }
+
+    public ActionModel getActionModel() {
+        return actionModel;
+    }
+
+    public Form<?> getForm() {
+        return form;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEnvelopeEvent.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEnvelopeEvent.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEnvelopeEvent.java
new file mode 100644
index 0000000..e072abe
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEnvelopeEvent.java
@@ -0,0 +1,64 @@
+/**
+ *  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.wicket.model.hints;
+
+
+import org.apache.wicket.event.IEvent;
+
+/**
+ * Broadcast down by <tt>PageAbstract</tt> to all child components
+ */
+public class IsisEnvelopeEvent extends IsisEventAbstract {
+
+    private final IsisEventLetterAbstract letter;
+
+    public IsisEnvelopeEvent(IsisEventLetterAbstract ev) {
+        super(ev.getTarget());
+        this.letter = ev;
+    }
+
+    public IsisEventLetterAbstract getLetter() {
+        return letter;
+    }
+
+    /**
+     * Opens the event, checks the event is an {@link org.apache.isis.viewer.wicket.model.hints.IsisEnvelopeEvent envelope} (event),
+     * fetches the {@link org.apache.isis.viewer.wicket.model.hints.IsisEventLetterAbstract letter} (event) inside, and
+     * returns if the letter is of the required type.
+     *
+     * <p>
+     * Otherwise returns <tt>null</tt>.
+     * </p>
+     */
+    public static <T> T openLetter(final IEvent<?> event, Class<T> letterEventClass) {
+        if(!(event.getPayload() instanceof IsisEnvelopeEvent)) {
+            return null;
+        }
+        final IsisEnvelopeEvent ev = (IsisEnvelopeEvent) event.getPayload();
+        final IsisEventLetterAbstract letter = ev.getLetter();
+        if(letter == null) {
+            return null;
+        }
+        if(!letterEventClass.isAssignableFrom(letter.getClass())) {
+            return null;
+        }
+        return letterEventClass.cast(letter);
+    }
+
+
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventAbstract.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventAbstract.java
new file mode 100644
index 0000000..b27777b
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventAbstract.java
@@ -0,0 +1,53 @@
+/**
+ *  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.wicket.model.hints;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+/**
+ * All Isis-related events subclass from this, and fall into two categories.
+ *
+ * <p>
+ * Components that are raising events should create a subclass of {@link org.apache.isis.viewer.wicket.model.hints.IsisEventLetterAbstract} (the letter)
+ * and then {@link org.apache.wicket.Component#send(org.apache.wicket.event.IEventSink, org.apache.wicket.event.Broadcast, Object) send} as a
+ * {@link org.apache.wicket.event.Broadcast#EXACT exact} message to <tt>PageAbstract</tt>.
+ * </p>
+ *
+ * <p>
+ * Then, <tt>PageAbstract</tt> will wrap the letter into the {@link org.apache.isis.viewer.wicket.model.hints.IsisEnvelopeEvent} (envelope) and
+ * send as a {@link org.apache.wicket.event.Broadcast#BREADTH down} to all its components.
+ * </p>
+ */
+public abstract class IsisEventAbstract {
+    
+    private final AjaxRequestTarget target;
+    
+    public IsisEventAbstract(AjaxRequestTarget target) {
+        this.target = target;
+    }
+
+    /**
+     * The {@link AjaxRequestTarget target}, if any, that caused this event to be generated.
+     * 
+     * <p>
+     * Typically populated, but not always...
+     */
+    public AjaxRequestTarget getTarget() {
+        return target;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventLetterAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventLetterAbstract.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventLetterAbstract.java
new file mode 100644
index 0000000..2361ba2
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisEventLetterAbstract.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.viewer.wicket.model.hints;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+/**
+ * All events to be propogated should inherit from this.
+ *
+ * <p>
+ *
+ * </p>
+ */
+public abstract class IsisEventLetterAbstract extends IsisEventAbstract {
+
+    public IsisEventLetterAbstract(AjaxRequestTarget target) {
+        super(target);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisUiHintEvent.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisUiHintEvent.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisUiHintEvent.java
new file mode 100644
index 0000000..a5ddbe7
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/IsisUiHintEvent.java
@@ -0,0 +1,38 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.viewer.wicket.model.hints;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+/**
+ *
+ */
+public class IsisUiHintEvent extends IsisEventLetterAbstract {
+    
+    private final UiHintContainer uiHintContainer;
+
+    public IsisUiHintEvent(UiHintContainer uiHintContainer, AjaxRequestTarget target) {
+        super(target);
+        this.uiHintContainer = uiHintContainer;
+    }
+
+    public UiHintContainer getUiHintContainer() {
+        return uiHintContainer;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
new file mode 100644
index 0000000..94b994b
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
@@ -0,0 +1,51 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.viewer.wicket.model.hints;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+public interface UiHintContainer {
+
+    String getHint(Component component, String key);
+    
+    void setHint(Component component, String key, String value);
+
+    void clearHint(Component component, String key);
+
+    public static class Util {
+        private Util(){}
+
+        public static UiHintContainer hintContainerOf(Component component) {
+            return hintContainerOf(component, UiHintContainer.class);
+        }
+
+        public static <T extends UiHintContainer> T hintContainerOf(
+                final Component component, final Class<T> additionalConstraint) {
+
+            if(component == null) {
+                return null;
+            }
+            IModel<?> model = component.getDefaultModel();
+            if(model != null && additionalConstraint.isAssignableFrom(model.getClass())) {
+                return additionalConstraint.cast(model);
+            }
+            return hintContainerOf(component.getParent(), additionalConstraint);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintPathSignificant.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintPathSignificant.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintPathSignificant.java
new file mode 100644
index 0000000..775ce99
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintPathSignificant.java
@@ -0,0 +1,21 @@
+/**
+ *  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.wicket.model.hints;
+
+public interface UiHintPathSignificant {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/PersistenceSessionProvider.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/PersistenceSessionProvider.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/PersistenceSessionProvider.java
new file mode 100644
index 0000000..3c6d78f
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/PersistenceSessionProvider.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.viewer.wicket.model.isis;
+
+
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+
+public interface PersistenceSessionProvider {
+
+    PersistenceSession getPersistenceSession();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/WicketViewerSettings.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/WicketViewerSettings.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/WicketViewerSettings.java
new file mode 100644
index 0000000..bc41422
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/isis/WicketViewerSettings.java
@@ -0,0 +1,43 @@
+/*
+ *  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.wicket.model.isis;
+
+import java.io.Serializable;
+
+
+public interface WicketViewerSettings extends Serializable {
+
+    public int getMaxTitleLengthInStandaloneTables();
+
+    public int getMaxTitleLengthInParentedTables();
+
+    public String getDatePattern();
+    public String getDateTimePattern();
+    public String getTimestampPattern();
+
+    /**
+     * @deprecated Not used since 1.8.0. Each Date scalar panel will use {@linkplain #getDatePattern()}
+     *             or {@linkplain #getDateTimePattern()} depending on its date type
+     */
+    @Deprecated
+    public String getDatePickerPattern();
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
new file mode 100644
index 0000000..19e1fd4
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
@@ -0,0 +1,132 @@
+/*
+ *  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.wicket.model.links;
+
+import java.io.Serializable;
+import java.util.List;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaPosition;
+
+public class LinkAndLabel implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    public static List<LinkAndLabel> positioned(
+            final List<LinkAndLabel> entityActionLinks,
+            final ActionLayout.Position position) {
+        return Lists.newArrayList(Iterables.filter(entityActionLinks, Predicates.positioned(position)));
+    }
+
+
+    private final AbstractLink link;
+    private final String label;
+    private final String disabledReasonIfAny;
+    private final String descriptionIfAny;
+    private final boolean blobOrClob;
+    private final boolean prototype;
+    private final String actionIdentifier;
+    private final String cssClass;
+    private final String cssClassFa;
+    private final CssClassFaPosition cssClassFaPosition;
+    private final ActionLayout.Position position;
+
+    public LinkAndLabel(
+            final AbstractLink link,
+            final String label,
+            final String disabledReasonIfAny,
+            final String descriptionIfAny,
+            final boolean blobOrClob,
+            final boolean prototype,
+            final String identifier,
+            final String cssClass,
+            final String cssClassFa,
+            final CssClassFaPosition cssClassFaPosition,
+            final ActionLayout.Position position) {
+        this.link = link;
+        this.label = label;
+        this.disabledReasonIfAny = disabledReasonIfAny;
+        this.descriptionIfAny = descriptionIfAny;
+        this.blobOrClob = blobOrClob;
+        this.prototype = prototype;
+        this.actionIdentifier = identifier;
+        this.cssClass = cssClass;
+        this.cssClassFa = cssClassFa;
+        this.cssClassFaPosition = cssClassFaPosition;
+        this.position = position;
+    }
+
+    public AbstractLink getLink() {
+        return link;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public String getDisabledReasonIfAny() {
+        return disabledReasonIfAny;
+    }
+
+    public String getDescriptionIfAny() {
+        return descriptionIfAny;
+    }
+
+    public boolean isBlobOrClob() {
+        return blobOrClob;
+    }
+
+    public boolean isPrototype() {
+        return prototype;
+    }
+
+    public String getActionIdentifier() {
+        return actionIdentifier;
+    }
+
+    public String getCssClass() {
+        return cssClass;
+    }
+
+    public String getCssClassFa() {
+        return cssClassFa;
+    }
+
+    public CssClassFaPosition getCssClassFaPosition() {
+        return cssClassFaPosition;
+    }
+
+    public ActionLayout.Position getPosition() {
+        return position;
+    }
+
+    public static class Predicates {
+        public static Predicate<LinkAndLabel> positioned(final ActionLayout.Position position) {
+            return new Predicate<LinkAndLabel>() {
+                @Override
+                public boolean apply(LinkAndLabel input) {
+                    return input.getPosition() == position;
+                }
+            };
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinksProvider.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinksProvider.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinksProvider.java
new file mode 100644
index 0000000..c65a220
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinksProvider.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.viewer.wicket.model.links;
+
+import java.util.List;
+
+import org.apache.wicket.markup.html.link.Link;
+
+import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
+
+/**
+ * For models - such as {@link EntityCollectionModel} - that can provide an
+ * additional list of {@link Link}s to be rendered.
+ */
+public interface LinksProvider {
+    List<LinkAndLabel> getLinks();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/ListOfLinksModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/ListOfLinksModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/ListOfLinksModel.java
new file mode 100644
index 0000000..0c98bbb
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/links/ListOfLinksModel.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.viewer.wicket.model.links;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.wicket.model.LoadableDetachableModel;
+
+
+public class ListOfLinksModel extends LoadableDetachableModel<List<LinkAndLabel>> {
+
+    private static final long serialVersionUID = 1L;
+    
+    private final List<LinkAndLabel> links;
+
+    public ListOfLinksModel(List<LinkAndLabel> links) {
+        // copy, in case supplied list is a non-serializable guava list using lazy evaluation;
+        this.links = Lists.newArrayList(links); 
+    }
+
+    @Override
+    protected List<LinkAndLabel> load() {
+        return links;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionMemento.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionMemento.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionMemento.java
new file mode 100644
index 0000000..509455c
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionMemento.java
@@ -0,0 +1,93 @@
+/*
+ *  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.wicket.model.mementos;
+
+import java.io.Serializable;
+
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
+/**
+ * {@link Serializable} represention of a {@link ObjectAction}
+ */
+public class ActionMemento implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    
+    private final ObjectSpecId owningType;
+    private final ActionType actionType;
+    private final String nameParmsId;
+    private final ActionSemantics.Of actionSemantics;
+
+    private transient ObjectAction action;
+
+    public ActionMemento(final ObjectAction action) {
+        this(action.getOnType().getSpecId(), action.getType(), action.getIdentifier().toNameParmsIdentityString(), action);
+    }
+
+    public ActionMemento(final ObjectSpecId owningType, final ActionType actionType, final String nameParmsId) {
+        this(owningType, actionType, nameParmsId, actionFor(owningType, actionType, nameParmsId));
+    }
+
+    private ActionMemento(
+            final ObjectSpecId owningSpecId, 
+            final ActionType actionType, 
+            final String nameParmsId, 
+            final ObjectAction action) {
+        this.owningType = owningSpecId;
+        this.actionType = actionType;
+        this.nameParmsId = nameParmsId;
+        this.action = action;
+        this.actionSemantics = action.getSemantics();
+    }
+    
+    public ObjectSpecId getOwningType() {
+        return owningType;
+    }
+
+    public ActionType getActionType() {
+        return actionType;
+    }
+
+    public String getNameParmsId() {
+        return nameParmsId;
+    }
+
+    public ConcurrencyChecking getConcurrencyChecking() {
+        return ConcurrencyChecking.concurrencyCheckingFor(this.actionSemantics);
+    }
+
+    public ObjectAction getAction() {
+        if (action == null) {
+            action = actionFor(owningType, actionType, nameParmsId);
+        }
+        return action;
+    }
+
+    private static ObjectAction actionFor(ObjectSpecId owningType, ActionType actionType, String nameParmsId) {
+        final ObjectSpecification objectSpec = SpecUtils.getSpecificationFor(owningType);
+        return objectSpec.getObjectAction(actionType, nameParmsId);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionParameterMemento.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionParameterMemento.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionParameterMemento.java
new file mode 100644
index 0000000..fd92b44
--- /dev/null
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ActionParameterMemento.java
@@ -0,0 +1,87 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.wicket.model.mementos;
+
+import java.io.Serializable;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+
+/**
+ * {@link Serializable} representation of a {@link ObjectActionParameter parameter}
+ * of a {@link ObjecObjectAction}.
+ * 
+ * @see ActionMemento
+ */
+public class ActionParameterMemento implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final ActionMemento actionMemento;
+    private final int number;
+
+    private transient ObjectActionParameter actionParameter;
+
+    public ActionParameterMemento(final ActionMemento actionMemento, final int number) {
+        this(actionMemento, number, actionParameterFor(actionMemento, number));
+    }
+
+    public ActionParameterMemento(final ObjectActionParameter actionParameter) {
+        this(new ActionMemento(actionParameter.getAction()), actionParameter.getNumber(), actionParameter);
+    }
+
+    private ActionParameterMemento(
+            final ActionMemento actionMemento, 
+            final int number, 
+            final ObjectActionParameter actionParameter) {
+        this.actionMemento = actionMemento;
+        this.number = number;
+        this.actionParameter = actionParameter;
+    }
+
+    public ActionMemento getActionMemento() {
+        return actionMemento;
+    }
+
+    public int getNumber() {
+        return number;
+    }
+
+    public ObjectActionParameter getActionParameter() {
+        if (actionParameter == null) {
+            this.actionParameter = actionParameterFor(actionMemento, number);
+        }
+        return actionParameter;
+    }
+
+    private static ObjectActionParameter actionParameterFor(ActionMemento actionMemento, int number) {
+        final ObjectAction action = actionMemento.getAction();
+        return action.getParameters().get(number);
+    }
+
+    /**
+     * Convenience.
+     */
+    public ObjectSpecification getSpecification() {
+        return getActionParameter().getSpecification();
+    }
+
+}