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 2016/01/08 11:28:24 UTC

[2/6] isis git commit: ISIS-993: metadata has back owners. Wicket component broken at this point

ISIS-993: metadata has back owners.  Wicket component broken at this point


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

Branch: refs/heads/ISIS-993
Commit: 165202f603ff7eb858f51f7f5a80df0f97e0b23d
Parents: b590c97
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Jan 8 08:50:03 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Jan 8 08:50:03 2016 +0000

----------------------------------------------------------------------
 .../src/main/asciidoc/guides/cg.adoc            |  31 ++++
 .../src/main/asciidoc/guides/rg.adoc            |  14 +-
 .../src/main/asciidoc/guides/ug.adoc            |   4 +-
 .../apache/isis/applib/layout/v1_0/Action.java  |  29 +++-
 .../isis/applib/layout/v1_0/ActionLayout.java   |  26 +++-
 .../isis/applib/layout/v1_0/Collection.java     |  23 ++-
 .../applib/layout/v1_0/CollectionLayout.java    |  27 +++-
 .../apache/isis/applib/layout/v1_0/Column.java  |  40 ++++-
 .../isis/applib/layout/v1_0/DomainObject.java   | 111 +++++++-------
 .../isis/applib/layout/v1_0/Property.java       |  25 +++-
 .../isis/applib/layout/v1_0/PropertyGroup.java  |  26 +++-
 .../isis/applib/layout/v1_0/PropertyLayout.java |  28 +++-
 .../org/apache/isis/applib/layout/v1_0/Tab.java |  29 +++-
 .../isis/applib/layout/v1_0/TabGroup.java       |  33 ++++-
 .../apache/isis/applib/layout/v1_0/Util.java    |  49 ++++++
 .../object/layoutxml/LayoutXmlFacetDefault.java | 148 ++++++++++++-------
 .../metamodel/spec/ObjectSpecifications.java    |  17 ++-
 .../spec/feature/ObjectAssociation.java         |   3 +-
 .../ComponentFactoryRegistrarDefault.java       |   4 +-
 .../viewer/wicket/model/models/EntityModel.java |  17 ++-
 .../collections/EntityCollectionsPanel.html     |   2 +-
 .../entity/properties/EntityPropertiesForm.java |  48 ++++--
 .../properties/EntityPropertiesPanel.html       |   6 +-
 .../EntityTabbedPanel$EntityTabPanel.html       |  29 ----
 .../entity/tabbed/EntityTabbedPanel.html        |  31 ----
 .../entity/tabbed/EntityTabbedPanel.java        | 114 --------------
 .../entity/tabbed/EntityTabbedPanelFactory.java |  56 -------
 .../EntityTabGroupsPanel$EntityTabPanel.html    |  29 ++++
 .../entity/tabgroups/EntityTabGroupsPanel.html  |  33 +++++
 .../entity/tabgroups/EntityTabGroupsPanel.java  | 119 +++++++++++++++
 .../tabgroups/EntityTabGroupsPanelFactory.java  |  56 +++++++
 .../dom/simple/SimpleObject.layout.xml          |  10 ++
 32 files changed, 833 insertions(+), 384 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/adocs/documentation/src/main/asciidoc/guides/cg.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/cg.adoc b/adocs/documentation/src/main/asciidoc/guides/cg.adoc
new file mode 100644
index 0000000..9437dc7
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/cg.adoc
@@ -0,0 +1,31 @@
+[[cg]]
+= "Supporting Procedures" Guides
+:Notice: 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.
+:_basedir: ../
+:_imagesdir: images/
+:numbered:
+
+
+Apache Isis documentation is broken out into a number of user, reference and "supporting procedures" guides.
+
+The user guides available are:
+
+* xref:ugfun.adoc#[Fundamentals]
+* xref:ugvw.adoc#[Wicket viewer]
+* xref:ugvro.adoc#[Restful Objects viewer]
+* xref:ugsec.adoc#[Security]
+* xref:ugtst.adoc#[Testing]
+* xref:ugbtb.adoc#[Beyond the Basics]
+
+The reference guides are:
+
+* xref:rgant.adoc#[Annotations]
+* xref:rgsvc.adoc#[Domain Services]
+* xref:rgcfg.adoc#[Configuration Properties]
+* xref:rgcms.adoc#[Classes, Methods and Schema]
+
+The *supporting procedures* guides are:
+
+* xref:cgcon.adoc#[Contributors' Guide] (how to set up a development environment
+for Apache Isis and contribute back to the project)
+* xref:cgcon.adoc#[Committers' Guide] (release procedures and related practices)

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/adocs/documentation/src/main/asciidoc/guides/rg.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/rg.adoc b/adocs/documentation/src/main/asciidoc/guides/rg.adoc
index fceaed5..f5f702f 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rg.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rg.adoc
@@ -6,16 +6,16 @@
 :numbered:
 
 
-Apache Isis documentation is broken out into a number of user and reference guides.
+Apache Isis documentation is broken out into a number of user, reference and "supporting procedures" guides.
 
-The user guides available are:
+The *user guides* available are:
 
 * xref:ugfun.adoc#[Fundamentals]
 * xref:ugvw.adoc#[Wicket viewer]
 * xref:ugvro.adoc#[Restful Objects viewer]
 * xref:ugsec.adoc#[Security]
 * xref:ugtst.adoc#[Testing]
-* xref:ugbtb.adoc#[Beyond the Basics] (this guide)
+* xref:ugbtb.adoc#[Beyond the Basics]
 
 The reference guides are:
 
@@ -24,6 +24,8 @@ The reference guides are:
 * xref:rgcfg.adoc#[Configuration Properties]
 * xref:rgcms.adoc#[Classes, Methods and Schema]
 
-In addition, there is a xref:cgcon.adoc#[Contributors' Guide] (that describes how to set up a development environment
-for Apache Isis and contribute back to the project), and a xref:cgcon.adoc#[Committers' Guide] (that describes release
-procedures and related practices).
+The "supporting procedures" guides are:
+
+* xref:cgcon.adoc#[Contributors' Guide] (how to set up a development environment
+for Apache Isis and contribute back to the project)
+* xref:cgcon.adoc#[Committers' Guide] (release procedures and related practices)

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/adocs/documentation/src/main/asciidoc/guides/ug.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ug.adoc b/adocs/documentation/src/main/asciidoc/guides/ug.adoc
index 6b07136..ee05c8f 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ug.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ug.adoc
@@ -8,14 +8,14 @@
 
 Apache Isis documentation is broken out into a number of user, reference and "supporting procedures" guides.
 
-The user guides available are:
+The *user guides* available are:
 
 * xref:ugfun.adoc#[Fundamentals]
 * xref:ugvw.adoc#[Wicket viewer]
 * xref:ugvro.adoc#[Restful Objects viewer]
 * xref:ugsec.adoc#[Security]
 * xref:ugtst.adoc#[Testing]
-* xref:ugbtb.adoc#[Beyond the Basics] (this guide)
+* xref:ugbtb.adoc#[Beyond the Basics]
 
 The reference guides are:
 

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Action.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Action.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Action.java
index 05aa54f..61c6443 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Action.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Action.java
@@ -18,8 +18,11 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlType(
@@ -29,7 +32,9 @@ import javax.xml.bind.annotation.XmlType;
                 , "layout"
         }
 )
-public class Action {
+public class Action implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     public Action() {
     }
@@ -57,7 +62,8 @@ public class Action {
 
 
     private ActionLayout layout;
-    @XmlElement(name="layout", required = false)
+
+    @XmlElement(name="layout", required = true)
     public ActionLayout getLayout() {
         return layout;
     }
@@ -65,4 +71,23 @@ public class Action {
     public void setLayout(ActionLayout layout) {
         this.layout = layout;
     }
+
+
+    private ActionHolder owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public ActionHolder getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final ActionHolder owner) {
+        this.owner = owner;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ActionLayout.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ActionLayout.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ActionLayout.java
index 0e12158..9068d91 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ActionLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ActionLayout.java
@@ -16,8 +16,11 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
@@ -37,7 +40,9 @@ import org.apache.isis.applib.annotation.Where;
                 , "describedAs"
         }
 )
-public class ActionLayout {
+public class ActionLayout implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     private BookmarkPolicy bookmarking;
 
@@ -151,4 +156,23 @@ public class ActionLayout {
         this.position = position;
     }
 
+
+
+    private Action owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public Action getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final Action owner) {
+        this.owner = owner;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Collection.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Collection.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Collection.java
index cf2dc48..db7d92b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Collection.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Collection.java
@@ -18,11 +18,13 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import com.google.common.collect.Lists;
@@ -34,8 +36,9 @@ import com.google.common.collect.Lists;
                 , "layout"
         }
 )
-public class Collection implements ColumnContent, ActionHolder {
+public class Collection implements ColumnContent, ActionHolder, Serializable {
 
+    private static final long serialVersionUID = 1L;
 
     public Collection() {
     }
@@ -87,5 +90,23 @@ public class Collection implements ColumnContent, ActionHolder {
     }
 
 
+    private Column owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public Column getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final Column owner) {
+        this.owner = owner;
+    }
+
+
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/CollectionLayout.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/CollectionLayout.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/CollectionLayout.java
index 4769b61..08f89fc 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/CollectionLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/CollectionLayout.java
@@ -17,8 +17,11 @@
 package org.apache.isis.applib.layout.v1_0;
 
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.isis.applib.annotation.Where;
@@ -38,7 +41,9 @@ import org.apache.isis.applib.annotation.Where;
                 ,"sortedBy"
         }
 )
-public class CollectionLayout {
+public class CollectionLayout implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     private String cssClass;
 
@@ -141,4 +146,24 @@ public class CollectionLayout {
     public void setSortedBy(String sortedBy) {
         this.sortedBy = sortedBy;
     }
+
+
+
+    private Collection owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public Collection getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final Collection owner) {
+        this.owner = owner;
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Column.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Column.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Column.java
index 3ac724e..7e7129c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Column.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Column.java
@@ -18,13 +18,16 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
 @XmlType(
@@ -33,8 +36,9 @@ import com.google.common.collect.Lists;
                 , "content"
         }
 )
-public class Column {
+public class Column implements Serializable {
 
+    private static final long serialVersionUID = 1L;
 
     public Column() {
     }
@@ -71,4 +75,38 @@ public class Column {
         this.content = content;
     }
 
+    @XmlTransient
+    public Iterable<PropertyGroup> getPropertyGroups() {
+        return Iterables.transform(
+                        Iterables.filter(getContent(), Util.is(PropertyGroup.class)),
+                        Util.cast(PropertyGroup.class));
+    }
+    @XmlTransient
+    public Iterable<Collection> getCollections() {
+        return Iterables.transform(
+                        Iterables.filter(getContent(), Util.is(Collection.class)),
+                        Util.cast(Collection.class));
+    }
+
+
+
+
+    private Tab owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public Tab getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final Tab owner) {
+        this.owner = owner;
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/DomainObject.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/DomainObject.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/DomainObject.java
index c5fa00d..4d89b47 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/DomainObject.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/DomainObject.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -27,9 +28,6 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.services.dto.Dto;
@@ -41,7 +39,9 @@ import org.apache.isis.applib.services.dto.Dto;
                 , "tabGroups"
         }
 )
-public class DomainObject implements Dto, ActionHolder {
+public class DomainObject implements Dto, ActionHolder, Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     private List<Action> actions = Lists.newArrayList();
 
@@ -81,17 +81,17 @@ public class DomainObject implements Dto, ActionHolder {
 
 
     public interface Visitor {
-        void visit(DomainObject domainObject);
-        void visit(TabGroup tabGroup);
-        void visit(Tab tab);
-        void visit(Column column);
-        void visit(PropertyGroup propertyGroup);
-        void visit(Property property);
-        void visit(@Nullable PropertyLayout propertyLayout, Property forProperty);
-        void visit(Collection collection);
-        void visit(@Nullable CollectionLayout collectionLayout, Collection forCollection);
-        void visit(Action action, ActionHolder holder);
-        void visit(@Nullable ActionLayout actionLayout, Action forAction);
+        void visit(final DomainObject domainObject);
+        void visit(final TabGroup tabGroup);
+        void visit(final Tab tab);
+        void visit(final Column column);
+        void visit(final PropertyGroup propertyGroup);
+        void visit(final Property property);
+        void visit(final PropertyLayout propertyLayout);
+        void visit(final Collection collection);
+        void visit(final CollectionLayout collectionLayout);
+        void visit(final Action action);
+        void visit(@Nullable final ActionLayout actionLayout);
     }
 
     public static class VisitorAdapter implements Visitor {
@@ -104,73 +104,80 @@ public class DomainObject implements Dto, ActionHolder {
         @Override
         public void visit(final Column column) { }
         @Override
-        public void visit(PropertyGroup propertyGroup) {}
+        public void visit(final PropertyGroup propertyGroup) {}
         @Override
-        public void visit(Property property) {}
+        public void visit(final Property property) {}
         @Override
-        public void visit(@Nullable final PropertyLayout propertyLayout, final Property forProperty) { }
+        public void visit(final PropertyLayout propertyLayout) { }
         @Override
-        public void visit(Collection collection) {}
+        public void visit(final Collection collection) {}
         @Override
-        public void visit(@Nullable final CollectionLayout collectionLayout, final Collection forCollection) { }
+        public void visit(final CollectionLayout collectionLayout) { }
         @Override
-        public void visit(final Action action, final ActionHolder actionHolder) { }
+        public void visit(final Action action) { }
         @Override
-        public void visit(@Nullable final ActionLayout actionLayout, final Action forAction) { }
+        public void visit(final ActionLayout actionLayout) { }
     }
 
+    /**
+     * Initializes all "owner" references across the graph, eg {@link TabGroup#setOwner(DomainObject)} and {@link Tab#setOwner(TabGroup)} .
+     */
+    public void init() {
+        visit(new VisitorAdapter());
+    }
 
     public void visit(final Visitor visitor) {
         visitor.visit(this);
         traverseActions(this, visitor);
         final List<TabGroup> tabGroups = getTabGroups();
         for (final TabGroup tabGroup : tabGroups) {
+            tabGroup.setOwner(this);
             visitor.visit(tabGroup);
             final List<Tab> tabs = tabGroup.getTabs();
             for (final Tab tab : tabs) {
+                tab.setOwner(tabGroup);
                 visitor.visit(tab);
-                traverseColumn(tab.getLeft(), visitor);
-                traverseColumn(tab.getMiddle(), visitor);
-                traverseColumn(tab.getRight(), visitor);
+                traverseColumn(tab.getLeft(), tab, visitor);
+                traverseColumn(tab.getMiddle(), tab, visitor);
+                traverseColumn(tab.getRight(), tab, visitor);
             }
         }
     }
 
-    private void traverseColumn(final Column column, final Visitor visitor) {
+    private void traverseColumn(final Column column, final Tab tab, final Visitor visitor) {
         if(column == null) {
             return;
         }
+        column.setOwner(tab);
         visitor.visit(column);
         traversePropertyGroups(column, visitor);
         traverseCollections(column, visitor);
     }
 
     private void traversePropertyGroups(final Column column, final Visitor visitor) {
-        List<ColumnContent> content = column.getContent();
-        final Iterable<PropertyGroup> propertyGroups =
-                Iterables.transform(
-                        Iterables.filter(content, is(PropertyGroup.class)),
-                        cast(PropertyGroup.class));
-        for (final PropertyGroup propertyGroup : propertyGroups) {
+        for (final PropertyGroup propertyGroup : column.getPropertyGroups()) {
+            propertyGroup.setOwner(column);
             visitor.visit(propertyGroup);
             traverseActions(propertyGroup, visitor);
             final List<Property> properties = propertyGroup.getProperties();
             for (final Property property : properties) {
+                property.setOwner(propertyGroup);
                 visitor.visit(property);
-                visitor.visit(property.getLayout(), property);
+                final PropertyLayout layout = property.getLayout();
+                layout.setOwner(property);
+                visitor.visit(layout);
                 traverseActions(property, visitor);
             }
         }
     }
 
     private void traverseCollections(final Column column, final Visitor visitor) {
-        final Iterable<Collection> collections =
-                Iterables.transform(
-                        Iterables.filter(column.getContent(), is(Collection.class)),
-                        cast(Collection.class));
-        for (final Collection collection : collections) {
+        for (final Collection collection : column.getCollections()) {
+            collection.setOwner(column);
             visitor.visit(collection);
-            visitor.visit(collection.getLayout(), collection);
+            final CollectionLayout layout = collection.getLayout();
+            layout.setOwner(collection);
+            visitor.visit(layout);
             traverseActions(collection, visitor);
         }
     }
@@ -178,27 +185,11 @@ public class DomainObject implements Dto, ActionHolder {
     private void traverseActions(final ActionHolder actionHolder, final Visitor visitor) {
         final List<Action> actions = actionHolder.getActions();
         for (final Action action : actions) {
-            visitor.visit(action, actionHolder);
-            visitor.visit(action.getLayout(), action);
-        }
-    }
-
-    private <F, T extends F> CastFunction<F, T> cast(final Class<T> cls) {
-        return new CastFunction<>();
-    }
-
-    private <F,T> Predicate<F> is(final Class<T> cls) {
-        return new Predicate<F>() {
-            @Override public boolean apply(@Nullable final F from) {
-                return cls.isAssignableFrom(from.getClass());
-            }
-        };
-    }
-
-    private static class CastFunction<F, T extends F> implements Function<F, T> {
-        @Override
-        public final T apply(final F from) {
-            return (T) from;
+            action.setOwner(actionHolder);
+            visitor.visit(action);
+            final ActionLayout layout = action.getLayout();
+            layout.setOwner(action);
+            visitor.visit(layout);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Property.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Property.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Property.java
index 5345d06..6f98d07 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Property.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Property.java
@@ -18,11 +18,13 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import com.google.common.collect.Lists;
@@ -34,7 +36,9 @@ import com.google.common.collect.Lists;
                 , "layout"
         }
 )
-public class Property implements ActionHolder {
+public class Property implements ActionHolder, Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     public Property() {
     }
@@ -85,4 +89,23 @@ public class Property implements ActionHolder {
     }
 
 
+
+
+    private PropertyGroup owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public PropertyGroup getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final PropertyGroup owner) {
+        this.owner = owner;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
index e7b169f..f249071 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
@@ -18,12 +18,14 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import com.google.common.collect.Lists;
@@ -37,7 +39,9 @@ import org.apache.isis.applib.annotation.MemberOrder;
                 , "properties"
         }
 )
-public class PropertyGroup implements ColumnContent, ActionHolder {
+public class PropertyGroup implements ColumnContent, ActionHolder, Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     public PropertyGroup() {
     }
@@ -92,4 +96,24 @@ public class PropertyGroup implements ColumnContent, ActionHolder {
     public void setProperties(List<Property> properties) {
         this.properties = properties;
     }
+
+
+    private Column owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public Column getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final Column owner) {
+        this.owner = owner;
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyLayout.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyLayout.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyLayout.java
index fff5086..7e67acf 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyLayout.java
@@ -16,8 +16,11 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.isis.applib.annotation.LabelPosition;
@@ -29,7 +32,9 @@ import org.apache.isis.applib.annotation.Where;
                 , "describedAs"
         }
 )
-public class PropertyLayout {
+public class PropertyLayout implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     private String cssClass;
 
@@ -137,4 +142,25 @@ public class PropertyLayout {
     public void setTypicalLength(Integer typicalLength) {
         this.typicalLength = typicalLength;
     }
+
+
+
+
+    private Property owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public Property getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final Property owner) {
+        this.owner = owner;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Tab.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Tab.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Tab.java
index 988d1e8..4a07dca 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Tab.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Tab.java
@@ -18,8 +18,11 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
+
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlType(
@@ -31,7 +34,9 @@ import javax.xml.bind.annotation.XmlType;
                 , "right"
         }
 )
-public class Tab {
+public class Tab implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     private String name;
 
@@ -80,4 +85,26 @@ public class Tab {
     public void setRight(final Column right) {
         this.right = right;
     }
+
+
+
+    private TabGroup owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public TabGroup getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final TabGroup owner) {
+        this.owner = owner;
+    }
+
+
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/TabGroup.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/TabGroup.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/TabGroup.java
index 2280ad6..60f39b8 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/TabGroup.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/TabGroup.java
@@ -18,22 +18,26 @@
  */
 package org.apache.isis.applib.layout.v1_0;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
-@XmlType(
-        //propOrder = {"tabs"}
-)
-public class TabGroup {
+@XmlType()
+public class TabGroup implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     // must be at least one tab.
     private List<Tab> tabs = new ArrayList<Tab>(){{
         add(new Tab());
     }};
 
+
+
     // no wrapper
     @XmlElement(name = "tab", required = true)
     public List<Tab> getTabs() {
@@ -43,4 +47,25 @@ public class TabGroup {
     public void setTabs(List<Tab> tabs) {
         this.tabs = tabs;
     }
+
+
+
+    private DomainObject owner;
+
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public DomainObject getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final DomainObject owner) {
+        this.owner = owner;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Util.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Util.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Util.java
new file mode 100644
index 0000000..6007850
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/Util.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.layout.v1_0;
+
+import javax.annotation.Nullable;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+class Util {
+
+    private Util(){}
+
+    static <F,T> Predicate<F> is(final Class<T> cls) {
+        return new Predicate<F>() {
+            @Override public boolean apply(@Nullable final F from) {
+                return cls.isAssignableFrom(from.getClass());
+            }
+        };
+    }
+
+    static <F, T extends F> CastFunction<F, T> cast(final Class<T> cls) {
+        return new CastFunction<>();
+    }
+
+    private static class CastFunction<F, T extends F> implements Function<F, T> {
+        @Override
+        public final T apply(final F from) {
+            return (T) from;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutxml/LayoutXmlFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutxml/LayoutXmlFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutxml/LayoutXmlFacetDefault.java
index e0b81d6..ad617e8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutxml/LayoutXmlFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutxml/LayoutXmlFacetDefault.java
@@ -58,6 +58,7 @@ import org.apache.isis.core.metamodel.facets.collections.layout.NamedFacetForCol
 import org.apache.isis.core.metamodel.facets.collections.layout.PagedFacetForCollectionLayoutXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.SortedByFacetForCollectionLayoutXml;
 import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetXml;
+import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.CssClassFacetForPropertyLayoutXml;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.DescribedAsFacetForPropertyLayoutXml;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.HiddenFacetForPropertyLayoutXml;
@@ -106,22 +107,22 @@ public class LayoutXmlFacetDefault
     }
 
 
-    private boolean derivedAndSynced;
+    private boolean derived;
 
     public DomainObject getLayoutMetadata() {
-        //return derivedAndSynced ? metadata : deriveAndSync(metadata);
-        return deriveAndSync(metadata);
+        //return derived ? metadata : deriveAndOverwrite(metadata);
+        return deriveAndOverwrite(metadata);
     }
 
-    private  DomainObject deriveAndSync(final DomainObject metadata) {
+    private  DomainObject deriveAndOverwrite(final DomainObject metadata) {
         synchronized (metadata) {
-            doDeriveAndSync(metadata);
-            derivedAndSynced = true;
+            doDeriveAndOverwrite(metadata);
+            derived = true;
         }
         return metadata;
     }
 
-    private void doDeriveAndSync(final DomainObject metadata) {
+    private void doDeriveAndOverwrite(final DomainObject metadata) {
 
         final ObjectSpecification objectSpec = (ObjectSpecification) getFacetHolder();
         final Map<String, OneToOneAssociation> oneToOneAssociationById =
@@ -132,11 +133,17 @@ public class LayoutXmlFacetDefault
                 ObjectMember.Util.mapById(objectSpec.getObjectActions(Contributed.INCLUDED));
 
         derive(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
-
-        sync(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
+        overwrite(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
     }
 
-    private void derive(
+    /**
+     * Ensures that all object members (properties, collections and actions) are in the metadata.
+     *
+     * <p>
+     *     If they are missing then they will be added to default tabs (created on the fly if need be).
+     * </p>
+     */
+    private static void derive(
             final DomainObject metadata,
             final Map<String, OneToOneAssociation> oneToOneAssociationById,
             final Map<String, OneToManyAssociation> oneToManyAssociationById,
@@ -144,10 +151,11 @@ public class LayoutXmlFacetDefault
         final List<String> propertyIds = Lists.newArrayList();
         final List<String> collectionIds = Lists.newArrayList();
         final List<String> actionIds = Lists.newArrayList();
-        final AtomicReference<PropertyGroup> generalPropertyGroupRef = new AtomicReference<>();
+        final AtomicReference<PropertyGroup> defaultPropertyGroupRef = new AtomicReference<>();
         final AtomicReference<Column> firstColumnRef = new AtomicReference<>();
         final AtomicReference<TabGroup> lastTabGroupRef = new AtomicReference<>();
 
+        // catalog which property, collection and action Ids appear (anywhere) in the metadata
         metadata.visit(new DomainObject.VisitorAdapter() {
             @Override
             public void visit(final Property property) {
@@ -158,17 +166,22 @@ public class LayoutXmlFacetDefault
                 collectionIds.add(collection.getId());
             }
             @Override
-            public void visit(final Action action, final ActionHolder holder) {
+            public void visit(final Action action) {
                 actionIds.add(action.getId());
             }
+        });
+
+        // capture the first column, and also
+        // capture the first property group (if any) with the default name ('General')
+        metadata.visit(new DomainObject.VisitorAdapter() {
             @Override
             public void visit(final Column column) {
                 firstColumnRef.compareAndSet(null, column);
             }
             @Override
             public void visit(final PropertyGroup propertyGroup) {
-                if(propertyGroup.getName().equals("General")) {
-                    generalPropertyGroupRef.compareAndSet(null, propertyGroup);
+                if(MemberGroupLayoutFacet.DEFAULT_GROUP.equals(propertyGroup.getName())) {
+                    defaultPropertyGroupRef.compareAndSet(null, propertyGroup);
                 }
             }
             @Override
@@ -178,20 +191,21 @@ public class LayoutXmlFacetDefault
         });
 
         // any missing properties will be added to the (first) 'General' property group found
-        // if there is no 'General' property group then one will be added to the first Column of the first Tab.
+        // if there is no default ('General') property group
+        // then one will be added to the first Column of the first Tab.
         final List<String> missingPropertyIds = Lists.newArrayList(oneToOneAssociationById.keySet());
         missingPropertyIds.removeAll(propertyIds);
 
         if(!missingPropertyIds.isEmpty()) {
             // ensure that there is a property group to use
-            boolean wasSet = generalPropertyGroupRef.compareAndSet(null, new PropertyGroup("General"));
-            final PropertyGroup generalPropertyGroup = generalPropertyGroupRef.get();
+            boolean wasSet = defaultPropertyGroupRef.compareAndSet(null, new PropertyGroup(MemberGroupLayoutFacet.DEFAULT_GROUP));
+            final PropertyGroup defaultPropertyGroup = defaultPropertyGroupRef.get();
             if(wasSet) {
-                firstColumnRef.get().getContent().add(generalPropertyGroup);
+                firstColumnRef.get().getContent().add(defaultPropertyGroup);
             }
             Iterables.removeAll(propertyIds, oneToOneAssociationById.keySet());
             for (final String propertyId : missingPropertyIds) {
-                generalPropertyGroup.getProperties().add(new Property(propertyId));
+                defaultPropertyGroup.getProperties().add(new Property(propertyId));
             }
         }
 
@@ -227,21 +241,22 @@ public class LayoutXmlFacetDefault
         }
     }
 
-    private void sync(
+    private void overwrite(
             final DomainObject metadata,
             final Map<String, OneToOneAssociation> oneToOneAssociationById,
             final Map<String, OneToManyAssociation> oneToManyAssociationById,
             final Map<String, ObjectAction> objectActionById) {
 
         metadata.visit(new DomainObject.VisitorAdapter() {
-            private int domainObjectSequence = 1;
-            private int propertyGroupSequence = 1;
-            private int propertySequence = 1;
-            private int collectionSequence = 1;
-            private Map<Action, ActionHolder> actionHolderByAction = Maps.newHashMap();
+            private final Map<String, int[]> propertySequenceByGroup = Maps.newHashMap();
+            private int actionDomainObjectSequence = 1;
+            private int actionPropertyGroupSequence = 1;
+            private int actionPropertySequence = 1;
+            private int actionCollectionSequence = 1;
+
             @Override
-            public void visit(final Action action, final ActionHolder actionHolder) {
-                actionHolderByAction.put(action, actionHolder);
+            public void visit(final Action action) {
+                final ActionHolder actionHolder = action.getOwner();
                 final ObjectAction objectAction = objectActionById.get(action.getId());
                 final String memberOrderName;
                 final int memberOrderSequence;
@@ -250,51 +265,48 @@ public class LayoutXmlFacetDefault
                     final List<Property> properties = propertyGroup.getProperties();
                     final Property property = properties.get(0); // any will do
                     memberOrderName = property.getId();
-                    memberOrderSequence = propertyGroupSequence++;
+                    memberOrderSequence = actionPropertyGroupSequence++;
                 } else if(actionHolder instanceof Property) {
                     final Property property = (Property) actionHolder;
                     memberOrderName = property.getId();
-                    memberOrderSequence = propertySequence++;
+                    memberOrderSequence = actionPropertySequence++;
                 } else if(actionHolder instanceof Collection) {
                     final Collection collection = (Collection) actionHolder;
                     memberOrderName = collection.getId();
-                    memberOrderSequence = collectionSequence++;
+                    memberOrderSequence = actionCollectionSequence++;
                 } else {
                     // DomainObject
                     memberOrderName = null;
-                    memberOrderSequence = domainObjectSequence++;
+                    memberOrderSequence = actionDomainObjectSequence++;
                 }
                 FacetUtil.addFacet(
                     new MemberOrderFacetXml(memberOrderName, ""+memberOrderSequence, translationService, objectAction));
             }
+
             @Override
-            public void visit(final ActionLayout actionLayout, final Action action) {
-                final ObjectAction objectAction = objectActionById.get(action.getId());
-                final ActionHolder actionHolder = actionHolderByAction.get(action);
+            public void visit(final ActionLayout actionLayout) {
+                final Action action = actionLayout.getOwner();
+                final ActionHolder actionHolder = action.getOwner();
 
-                final ActionLayout actionLayoutForPosition;
                 if(actionHolder instanceof PropertyGroup) {
-                    // ensure that there is a non-null valid ActionLayout#position()
-                    actionLayoutForPosition = actionLayout != null ? actionLayout : new ActionLayout();
-                    if(     actionLayoutForPosition.getPosition() == null ||
-                            actionLayoutForPosition.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
-                            actionLayoutForPosition.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.RIGHT) {
-                        actionLayoutForPosition.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.PANEL);
+                    if(actionLayout.getPosition() == null ||
+                       actionLayout.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
+                       actionLayout.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.RIGHT) {
+                       actionLayout.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.PANEL);
                     }
                 } else if(actionHolder instanceof Property) {
-                    // ensure that there is a non-null valid ActionLayout#position()
-                    actionLayoutForPosition = actionLayout != null ? actionLayout : new ActionLayout();
-                    if(     actionLayoutForPosition.getPosition() == null ||
-                            actionLayoutForPosition.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL_DROPDOWN ||
-                            actionLayoutForPosition.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL) {
-                        actionLayoutForPosition.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.BELOW);
+                    if(actionLayout.getPosition() == null ||
+                       actionLayout.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL_DROPDOWN ||
+                       actionLayout.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL) {
+                       actionLayout.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.BELOW);
                     }
                 } else {
                     // doesn't do anything for DomainObject or Collection
-                    actionLayoutForPosition = null;
+                    actionLayout.setPosition(null);
                 }
-                FacetUtil.addFacet(ActionPositionFacetForActionLayoutXml.create(actionLayoutForPosition, objectAction));
 
+                final ObjectAction objectAction = objectActionById.get(action.getId());
+                FacetUtil.addFacet(ActionPositionFacetForActionLayoutXml.create(actionLayout, objectAction));
                 FacetUtil.addFacet(BookmarkPolicyFacetForActionLayoutXml.create(actionLayout, objectAction));
                 FacetUtil.addFacet(CssClassFacetForActionLayoutXml.create(actionLayout, objectAction));
                 FacetUtil.addFacet(CssClassFaFacetForActionLayoutXml.create(actionLayout, objectAction));
@@ -302,8 +314,11 @@ public class LayoutXmlFacetDefault
                 FacetUtil.addFacet(HiddenFacetForActionLayoutXml.create(actionLayout, objectAction));
                 FacetUtil.addFacet(NamedFacetForActionLayoutXml.create(actionLayout, objectAction));
             }
+
             @Override
-            public void visit(final PropertyLayout propertyLayout, final Property property) {
+            public void visit(final PropertyLayout propertyLayout) {
+                final Property property = propertyLayout.getOwner();
+
                 final OneToOneAssociation oneToOneAssociation = oneToOneAssociationById.get(property.getId());
                 FacetUtil.addFacet(CssClassFacetForPropertyLayoutXml.create(propertyLayout, oneToOneAssociation));
                 FacetUtil.addFacet(DescribedAsFacetForPropertyLayoutXml.create(propertyLayout, oneToOneAssociation));
@@ -313,10 +328,20 @@ public class LayoutXmlFacetDefault
                 FacetUtil.addFacet(NamedFacetForPropertyLayoutXml.create(propertyLayout, oneToOneAssociation));
                 FacetUtil.addFacet(RenderedAdjustedFacetForPropertyLayoutXml.create(propertyLayout, oneToOneAssociation));
                 FacetUtil.addFacet(TypicalLengthFacetForPropertyLayoutXml.create(propertyLayout, oneToOneAssociation));
+
+                // @MemberOrder#name based on owning property group, @MemberOrder#sequence monotonically increasing
+                final PropertyGroup propertyGroup = property.getOwner();
+                final String groupName = propertyGroup.getName();
+                final String sequence = nextInSequenceFor(groupName);
+                FacetUtil.addFacet(
+                        new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
             }
+
             @Override
-            public void visit(final CollectionLayout collectionLayout, final Collection collection) {
+            public void visit(final CollectionLayout collectionLayout) {
+                final Collection collection = collectionLayout.getOwner();
                 final OneToManyAssociation oneToManyAssociation = oneToManyAssociationById.get(collection.getId());
+
                 FacetUtil.addFacet(CssClassFacetForCollectionLayoutXml.create(collectionLayout, oneToManyAssociation));
                 FacetUtil.addFacet(DefaultViewFacetForCollectionLayoutXml.create(collectionLayout, oneToManyAssociation));
                 FacetUtil.addFacet(DescribedAsFacetForCollectionLayoutXml.create(collectionLayout, oneToManyAssociation));
@@ -324,17 +349,34 @@ public class LayoutXmlFacetDefault
                 FacetUtil.addFacet(NamedFacetForCollectionLayoutXml.create(collectionLayout, oneToManyAssociation));
                 FacetUtil.addFacet(PagedFacetForCollectionLayoutXml.create(collectionLayout, oneToManyAssociation));
                 FacetUtil.addFacet(SortedByFacetForCollectionLayoutXml.create(collectionLayout, oneToManyAssociation));
+
+                // copy the collection name onto the tab
+                final Column column = collection.getOwner();
+                final Tab tab = column.getOwner();
+                tab.setName(collection.getId());
+            }
+
+            private String nextInSequenceFor(final String propertyGroupName) {
+                synchronized (propertySequenceByGroup) {
+                    int[] holder = propertySequenceByGroup.get(propertyGroupName);
+                    if(holder == null) {
+                        holder = new int[]{0};
+                        propertySequenceByGroup.put(propertyGroupName, holder);
+                    }
+                    holder[0]++;
+                    return ""+holder[0];
+                }
             }
         });
 
     }
 
-    private List<OneToOneAssociation> getOneToOneAssociations(final ObjectSpecification objectSpec) {
+    private static List<OneToOneAssociation> getOneToOneAssociations(final ObjectSpecification objectSpec) {
         List associations = objectSpec
                 .getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.PROPERTIES);
         return associations;
     }
-    private List<OneToManyAssociation> getOneToManyAssociations(final ObjectSpecification objectSpec) {
+    private static List<OneToManyAssociation> getOneToManyAssociations(final ObjectSpecification objectSpec) {
         List associations = objectSpec
                 .getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.COLLECTIONS);
         return associations;

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
index 9a7cc67..7fee60b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
@@ -26,6 +26,8 @@ import java.util.Set;
 import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.annotation.MemberGroupLayout.ColumnSpans;
+import org.apache.isis.applib.layout.v1_0.Column;
+import org.apache.isis.applib.layout.v1_0.Tab;
 import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 
 
@@ -43,11 +45,22 @@ public final class ObjectSpecifications {
             if(this == LEFT) return columnSpans.getLeft();
             if(this == MIDDLE) return columnSpans.getMiddle();
             if(this == RIGHT) return columnSpans.getRight();
-            return 0;
+            throw new IllegalStateException();
+        }
+
+        public Column from(final Tab tab) {
+            if(this == LEFT) {return tab.getLeft();}
+            if(this == MIDDLE) return tab.getMiddle();
+            if(this == RIGHT) return tab.getRight();
+            throw new IllegalStateException();
         }
     }
 
-    public static List<String> orderByMemberGroups(ObjectSpecification objSpec, Set<String> groupNamesToOrder, MemberGroupLayoutHint memberGroupLayoutHint) {
+    public static List<String> orderByMemberGroups(
+            final ObjectSpecification objSpec,
+            final Set<String> groupNamesToOrder,
+            final MemberGroupLayoutHint memberGroupLayoutHint) {
+
         final MemberGroupLayoutFacet facet = objSpec.getFacet(MemberGroupLayoutFacet.class);
         final List<String> leftColumnGroupNames = Lists.newArrayList(groupNamesToOrder);
         

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
index 5e74780..8837916 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
@@ -36,6 +36,7 @@ import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
+import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
 import org.apache.isis.core.metamodel.specloader.specimpl.ContributeeMember;
 
@@ -418,7 +419,7 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
                     return;
                 }
             }
-            getFrom(associationsByGroup, "General").add(association);
+            getFrom(associationsByGroup, MemberGroupLayoutFacet.DEFAULT_GROUP).add(association);
         }
 
         private static List<ObjectAssociation> getFrom(Map<String, List<ObjectAssociation>> associationsByGroup, final String groupName) {

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index 75b0e71..befd252 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -46,7 +46,7 @@ import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconAn
 import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconTitleAndCopyLinkPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.properties.EntityPropertiesPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.selector.links.EntityLinksSelectorPanelFactory;
-import org.apache.isis.viewer.wicket.ui.components.entity.tabbed.EntityTabbedPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.entity.tabgroups.EntityTabGroupsPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.footer.FooterPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.header.HeaderPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisBlobPanelFactory;
@@ -167,7 +167,7 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
     protected void addComponentFactoriesForEntity(final ComponentFactoryList componentFactories) {
 
         // top-level
-        componentFactories.add(new EntityTabbedPanelFactory());
+        componentFactories.add(new EntityTabGroupsPanelFactory());
         componentFactories.add(new EntityCombinedPanelFactory());
 
         // lower-level

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index fde03d7..97ef07c 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -29,6 +29,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
+import org.apache.isis.applib.layout.v1_0.Tab;
 import org.apache.isis.applib.services.memento.MementoService.Memento;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
@@ -633,9 +634,23 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
 
 
     // //////////////////////////////////////////////////////////
+    // tab (if any)
+    // //////////////////////////////////////////////////////////
+
+    private Tab tab;
+
+    public Tab getTab() {
+        return tab;
+    }
+
+    public void setTab(final Tab tab) {
+        this.tab = tab;
+    }
+
+    // //////////////////////////////////////////////////////////
     // equals, hashCode
     // //////////////////////////////////////////////////////////
-    
+
     @Override
     public int hashCode() {
         final int prime = 31;

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collections/EntityCollectionsPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collections/EntityCollectionsPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collections/EntityCollectionsPanel.html
index 2d39517..f46ec4a 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collections/EntityCollectionsPanel.html
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collections/EntityCollectionsPanel.html
@@ -38,7 +38,7 @@
                             </div>
                         </div>
 
-                        <div wicket:id="collection" class="collection panel-body">
+                        <div wicket:id="owner" class="collection panel-body">
                             [collection]
                         </div>
                     </div>

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
index 1f7f638..8339981 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
@@ -21,6 +21,10 @@ package org.apache.isis.viewer.wicket.ui.components.entity.properties;
 import java.util.List;
 import java.util.Map;
 
+import javax.annotation.Nullable;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
 import org.apache.wicket.Component;
@@ -49,6 +53,9 @@ import org.apache.isis.applib.annotation.MemberGroupLayout.ColumnSpans;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.filter.Filters;
+import org.apache.isis.applib.layout.v1_0.Column;
+import org.apache.isis.applib.layout.v1_0.PropertyGroup;
+import org.apache.isis.applib.layout.v1_0.Tab;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
 import org.apache.isis.core.commons.authentication.MessageBroker;
@@ -147,9 +154,17 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
     private void buildGui() {
 
         final EntityModel entityModel = (EntityModel) getModel();
-        MemberGroupLayoutFacet memberGroupLayoutFacet =
-                entityModel.getObject().getSpecification().getFacet(MemberGroupLayoutFacet.class);
-        final ColumnSpans columnSpans = memberGroupLayoutFacet.getColumnSpans();
+
+        final Tab tabIfAny = entityModel.getTab();
+
+        final ColumnSpans columnSpans;
+        if(tabIfAny != null) {
+            columnSpans = ColumnSpans.asSpans(tabIfAny.getLeft().getSpan(), tabIfAny.getMiddle().getSpan(), tabIfAny.getRight().getSpan());
+        } else {
+            final MemberGroupLayoutFacet memberGroupLayoutFacet =
+                    entityModel.getObject().getSpecification().getFacet(MemberGroupLayoutFacet.class);
+            columnSpans = memberGroupLayoutFacet.getColumnSpans();
+        }
 
         renderedFirstField = false;
         
@@ -159,7 +174,7 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
         
         boolean addedProperties;
         if(columnSpans.getLeft() > 0) {
-            addedProperties = addPropertiesInColumn(leftColumn, MemberGroupLayoutHint.LEFT, columnSpans);
+            addedProperties = addPropertiesInColumn(leftColumn, MemberGroupLayoutHint.LEFT, tabIfAny, columnSpans);
             addButtons(leftColumn);
             addFeedbackGui(leftColumn);
         } else {
@@ -177,7 +192,7 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
         if(columnSpans.getMiddle() > 0) {
             MarkupContainer middleColumn = new WebMarkupContainer(ID_MIDDLE_COLUMN);
             add(middleColumn);
-            addPropertiesInColumn(middleColumn, MemberGroupLayoutHint.MIDDLE, columnSpans);
+            addPropertiesInColumn(middleColumn, MemberGroupLayoutHint.MIDDLE, tabIfAny, columnSpans);
         } else {
             Components.permanentlyHide(this, ID_MIDDLE_COLUMN);
         }
@@ -186,7 +201,7 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
         if(columnSpans.getRight() > 0) {
             MarkupContainer rightColumn = new WebMarkupContainer(ID_RIGHT_COLUMN);
             add(rightColumn);
-            addPropertiesInColumn(rightColumn, MemberGroupLayoutHint.RIGHT, columnSpans);
+            addPropertiesInColumn(rightColumn, MemberGroupLayoutHint.RIGHT, tabIfAny, columnSpans);
         } else {
             Components.permanentlyHide(this, ID_RIGHT_COLUMN);
         }
@@ -220,6 +235,7 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
     private boolean addPropertiesInColumn(
             final MarkupContainer markupContainer,
             final MemberGroupLayoutHint hint,
+            final Tab tabIfAny,
             final ColumnSpans columnSpans) {
         final int span = hint.from(columnSpans);
         
@@ -234,10 +250,15 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
 
         final Map<String, List<ObjectAssociation>> associationsByGroup = ObjectAssociation.Util.groupByMemberOrderName(associations);
         
-        final List<String> groupNames = ObjectSpecifications.orderByMemberGroups(objSpec, associationsByGroup.keySet(), hint);
-
+        final List<String> groupNames;
+        if(tabIfAny != null) {
+            final Column column = hint.from(tabIfAny);
+            groupNames = Lists.newArrayList(Iterables.transform(column.getPropertyGroups(), propertyGroupName()));
+        } else {
+            groupNames = ObjectSpecifications.orderByMemberGroups(objSpec, associationsByGroup.keySet(), hint);
+        }
 
-        for(String groupName: groupNames) {
+        for(final String groupName: groupNames) {
             final List<ObjectAssociation> associationsInGroup = associationsByGroup.get(groupName);
             if(associationsInGroup==null) {
                 continue;
@@ -278,6 +299,15 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
         return !groupNames.isEmpty();
     }
 
+    private static Function<? super PropertyGroup, String> propertyGroupName() {
+        return new Function<PropertyGroup, String>() {
+            @Nullable @Override
+            public String apply(@Nullable final PropertyGroup propertyGroup) {
+                return propertyGroup.getName();
+            }
+        };
+    }
+
     private void addPropertyToForm(
             final EntityModel entityModel,
             final OneToOneAssociation otoa,

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesPanel.html
index e65c157..afff1d6 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesPanel.html
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesPanel.html
@@ -36,7 +36,7 @@
                                         </div>
                                         <div class="properties panel-body">
                                             <div wicket:id="properties">
-                                                <div wicket:id="property" class="property">[property]</div>
+                                                <div wicket:id="owner" class="property">[property]</div>
                                             </div>
                                         </div>
                                     </div>
@@ -64,7 +64,7 @@
                                         </div>
                                         <div class="properties panel-body">
                                             <div wicket:id="properties">
-                                                <div wicket:id="property" class="property">[property]</div>
+                                                <div wicket:id="owner" class="property">[property]</div>
                                             </div>
                                         </div>
                                     </div>
@@ -84,7 +84,7 @@
                                         </div>
                                         <div class="properties panel-body">
                                             <div wicket:id="properties">
-                                                <div wicket:id="property" class="property">[property]</div>
+                                                <div wicket:id="owner" class="property">[property]</div>
                                             </div>
                                         </div>
                                     </div>

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel$EntityTabPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel$EntityTabPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel$EntityTabPanel.html
deleted file mode 100644
index 94582b1..0000000
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel$EntityTabPanel.html
+++ /dev/null
@@ -1,29 +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.
--->
-<html xmlns:wicket="http://wicket.apache.org">
-<body>
-<wicket:panel>
-	<div class="tabPanel">
-        <div wicket:id="entityPropertiesAndCollections"></div>
-
-	</div>
-</wicket:panel>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.html
deleted file mode 100644
index 999a22e..0000000
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.html
+++ /dev/null
@@ -1,31 +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.
--->
-<html xmlns:wicket="http://wicket.apache.org">
-<body>
-<wicket:panel>
-	<div class="entityTabbed">
-		<div wicket:id="entitySummary"></div>
-
-        <div wicket:id="tabs">[tabbed panel will be here]</div>
-
-	</div>
-</wicket:panel>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.java
deleted file mode 100644
index c1c65ba..0000000
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanel.java
+++ /dev/null
@@ -1,114 +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.wicket.ui.components.entity.tabbed;
-
-import java.util.List;
-
-import com.google.common.collect.Lists;
-
-import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
-import org.apache.wicket.extensions.markup.html.tabs.ITab;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.Model;
-
-import org.apache.isis.applib.layout.v1_0.DomainObject;
-import org.apache.isis.applib.layout.v1_0.Tab;
-import org.apache.isis.applib.layout.v1_0.TabGroup;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
-import org.apache.isis.core.metamodel.facets.object.layoutxml.LayoutXmlFacet;
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
-import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
-
-/**
- * {@link PanelAbstract Panel} to represent an entity on a single page made up
- * of several &lt;div&gt; regions.
- */
-public class EntityTabbedPanel extends PanelAbstract<EntityModel> {
-
-    private static final long serialVersionUID = 1L;
-
-    private static final String ID_ENTITY_PROPERTIES_AND_COLLECTIONS = "entityPropertiesAndCollections";
-
-    
-    public EntityTabbedPanel(final String id, final EntityModel entityModel) {
-        super(id, entityModel);
-        buildGui();
-    }
-
-    private void buildGui() {
-        final EntityModel model = getModel();
-        final ObjectAdapter objectAdapter = model.getObject();
-        final CssClassFacet facet = objectAdapter.getSpecification().getFacet(CssClassFacet.class);
-        if(facet != null) {
-            final String cssClass = facet.cssClass(objectAdapter);
-            CssClassAppender.appendCssClassTo(this, cssClass);
-        }
-
-        // forces metadata to be derived && synced
-        final LayoutXmlFacet layoutXmlFacet = model.getTypeOfSpecification().getFacet(LayoutXmlFacet.class);
-        final DomainObject domainObject = layoutXmlFacet.getLayoutMetadata();
-
-
-        addOrReplace(ComponentType.ENTITY_SUMMARY, model);
-
-
-        List<TabGroup> tabGroups = domainObject.getTabGroups();
-        TabGroup tabGroup = tabGroups.get(0);
-
-        List<ITab> tabs = Lists.newArrayList();
-        List<Tab> tabList = tabGroup.getTabs();
-
-        for (Tab tab : tabList) {
-
-            tabs.add(new AbstractTab(Model.of(tab.getName())) {
-                private static final long serialVersionUID = 1L;
-
-                @Override
-                public Panel getPanel(String panelId) {
-                    return new EntityTabPanel(panelId, getModel());
-                }
-
-            });
-
-        }
-
-
-        addOrReplace(new AjaxBootstrapTabbedPanel("tabs", tabs));
-
-    }
-
-    private static class EntityTabPanel extends PanelAbstract {
-        private static final long serialVersionUID = 1L;
-
-        public EntityTabPanel(String id, final EntityModel model) {
-            super(id);
-            getComponentFactoryRegistry().addOrReplaceComponent(this, ID_ENTITY_PROPERTIES_AND_COLLECTIONS, ComponentType.ENTITY_PROPERTIES, model);
-
-        }
-
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanelFactory.java
deleted file mode 100644
index 04c3496..0000000
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabbed/EntityTabbedPanelFactory.java
+++ /dev/null
@@ -1,56 +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.wicket.ui.components.entity.tabbed;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.model.IModel;
-
-import org.apache.isis.core.metamodel.facets.object.layoutxml.LayoutXmlFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
-import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.components.entity.EntityComponentFactoryAbstract;
-
-/**
- * {@link ComponentFactory} for {@link EntityTabbedPanel}.
- */
-public class EntityTabbedPanelFactory extends EntityComponentFactoryAbstract {
-
-    private static final long serialVersionUID = 1L;
-
-    private static final String NAME = "tabbed";
-
-    public EntityTabbedPanelFactory() {
-        super(ComponentType.ENTITY, NAME, EntityTabbedPanel.class);
-    }
-
-    @Override
-    protected ApplicationAdvice doAppliesTo(final EntityModel entityModel) {
-        final ObjectSpecification specification = entityModel.getTypeOfSpecification();
-        return appliesIf(specification.containsDoOpFacet(LayoutXmlFacet.class));
-    }
-
-    @Override
-    public Component createComponent(final String id, final IModel<?> model) {
-        final EntityModel entityModel = (EntityModel) model;
-        return new EntityTabbedPanel(id, entityModel);
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel$EntityTabPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel$EntityTabPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel$EntityTabPanel.html
new file mode 100644
index 0000000..94582b1
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel$EntityTabPanel.html
@@ -0,0 +1,29 @@
+<?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.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<body>
+<wicket:panel>
+	<div class="tabPanel">
+        <div wicket:id="entityPropertiesAndCollections"></div>
+
+	</div>
+</wicket:panel>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/165202f6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.html
new file mode 100644
index 0000000..ebe6c63
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.html
@@ -0,0 +1,33 @@
+<?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.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<body>
+<wicket:panel>
+	<div class="entityTabbed">
+		<div wicket:id="entitySummary"></div>
+
+        <div wicket:id="tabGroups">
+            <div wicket:id="tabGroup">[tabbed panel will be here]</div>
+        </div>
+
+	</div>
+</wicket:panel>
+</body>
+</html>