You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by jo...@apache.org on 2021/06/16 17:12:39 UTC

[isis] 02/03: ISIS-2505 CollectionAggregator invokes additional link; some debug aids added

This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch ISIS-2505_Catch_Up_With_Demo_Examples
in repository https://gitbox.apache.org/repos/asf/isis.git

commit c27b609049a0ecae77c8d58806fa3bd3602dfded
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Fri Jun 11 18:23:54 2021 +0200

    ISIS-2505 CollectionAggregator invokes additional link; some debug aids added
---
 .../kroviz/core/aggregator/AggregatorWithLayout.kt |   6 +-
 .../kroviz/core/aggregator/CollectionAggregator.kt |  29 +-
 .../kroviz/core/aggregator/ObjectAggregator.kt     |  26 +-
 .../isis/client/kroviz/core/event/EventStore.kt    |   9 +-
 .../isis/client/kroviz/core/event/LogEntry.kt      |  20 +-
 .../isis/client/kroviz/core/model/CollectionDM.kt  |  12 +-
 .../isis/client/kroviz/core/model/ObjectDM.kt      |  18 +-
 .../isis/client/kroviz/handler/ActionHandler.kt    |   4 +
 .../client/kroviz/handler/CollectionHandler.kt     |   1 -
 .../org/apache/isis/client/kroviz/to/Link.kt       |   1 +
 .../org/apache/isis/client/kroviz/to/bs3/Col.kt    |  15 +
 .../apache/isis/client/kroviz/to/bs3/Collection.kt |  59 ++++
 .../isis/client/kroviz/ui/builder/ColBuilder.kt    |  20 +-
 .../client/kroviz/ui/builder/FieldSetBuilder.kt    |   4 +-
 .../isis/client/kroviz/ui/core/FormPanelFactory.kt |  26 +-
 .../apache/isis/client/kroviz/ui/core/RoDisplay.kt |   2 -
 .../apache/isis/client/kroviz/ui/core/RoView.kt    |  10 +-
 .../apache/isis/client/kroviz/ui/core/UiManager.kt |   4 +-
 .../client/kroviz/ui/dialog/EventExportDialog.kt   |   3 +-
 .../isis/client/kroviz/ui/dialog/EventLogDetail.kt |  53 ++-
 .../apache/isis/client/kroviz/utils/XmlHelper.kt   |   2 +-
 .../client/kroviz/handler/ActionHandlerTest.kt     |  29 +-
 .../snapshots/demo2_0_0/COLLECTION_DESCRIPTION.kt  |  51 +++
 .../snapshots/demo2_0_0/JAVA_LANG_STRING_ENTITY.kt | 262 +++++++++++++++
 ...OLLECTIONS_ENTITIES.kt => OBJECT_COLLECTION.kt} |   2 +-
 .../kroviz/snapshots/demo2_0_0/Response2Handler.kt |   2 +-
 .../snapshots/demo2_0_0/STRINGS_LAYOUT_XML.kt      | 217 +++++++++++++
 .../isis/client/kroviz/snapshots/sample.json       | 212 ++----------
 .../apache/isis/client/kroviz/snapshots/sample.xml | 354 +++++++++------------
 .../apache/isis/client/kroviz/to/CollectionTest.kt |   4 +-
 .../apache/isis/client/kroviz/to/DomainTypeTest.kt |  11 +
 .../org/apache/isis/client/kroviz/to/LinkTest.kt   |   4 +-
 .../org/apache/isis/client/kroviz/to/MemberTest.kt |   9 +
 .../isis/client/kroviz/to/bs3/LayoutXmlTest.kt     |  33 +-
 34 files changed, 1020 insertions(+), 494 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt
index 1b1901b..decb30b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt
@@ -22,12 +22,12 @@ abstract class AggregatorWithLayout : BaseAggregator() {
         }
     }
 
-    protected fun invokeLayoutLink(obj: TObject) {
+    protected fun invokeLayoutLink(obj: TObject, aggregator: AggregatorWithLayout) {
         val l = obj.getLayoutLink()!!
         if (l.representation() == Represention.OBJECT_LAYOUT_BS3) {
-            invoke(l, this, Constants.subTypeXml)
+            invoke(l, aggregator, Constants.subTypeXml)
         } else {
-            invoke(l, this)
+            invoke(l, aggregator)
         }
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/CollectionAggregator.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/CollectionAggregator.kt
index c114c38..400788a 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/CollectionAggregator.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/CollectionAggregator.kt
@@ -49,6 +49,7 @@ class CollectionAggregator(actionTitle: String, val parent: ObjectAggregator? =
                 null -> log(logEntry)
                 is ResultList -> handleList(obj)
                 is TObject -> handleObject(obj)
+                is DomainType -> handleDomainType(obj)
                 is Layout -> handleLayout(obj, dpm as CollectionDM)
                 is Grid -> handleGrid(obj)
                 is Property -> handleProperty(obj)
@@ -61,8 +62,8 @@ class CollectionAggregator(actionTitle: String, val parent: ObjectAggregator? =
                     UiManager.openCollectionView(this)
                 }
             } else {
-                console.log("[CA.opdate] can be displayed / parent = OA")
-                parent.update(logEntry, subType)
+                val le = LogEntry("")
+                parent.update(le, subType)
             }
         }
     }
@@ -77,13 +78,20 @@ class CollectionAggregator(actionTitle: String, val parent: ObjectAggregator? =
     }
 
     private fun handleObject(obj: TObject) {
-        console.log("[CA.handleObject]")
-        console.log(obj)
         dpm.addData(obj)
-        invokeLayoutLink(obj)
+        invokeLayoutLink(obj, this)
 //TODO        invokeIconLink(obj)
     }
 
+    private fun handleDomainType(obj: DomainType) {
+        console.log("[CA.handleDomainType]")
+        obj.links.forEach {
+            if (it.relation() == Relation.LAYOUT) {
+                console.log(it)
+                invoke(it, this)
+            }
+        }
+    }
 
     private fun handleGrid(grid: Grid) {
         (dpm as CollectionDM).grid = grid
@@ -91,6 +99,7 @@ class CollectionAggregator(actionTitle: String, val parent: ObjectAggregator? =
 
     private fun handleProperty(p: Property) {
         val dm = dpm as CollectionDM
+        console.log("[CA.handleProperty]")
         if (p.isPropertyDescription()) {
             dm.addPropertyDescription(p)
         } else {
@@ -100,8 +109,12 @@ class CollectionAggregator(actionTitle: String, val parent: ObjectAggregator? =
     }
 
     private fun handleCollection(collection: Collection) {
+        collection.links.forEach {
+            if (it.relation() == Relation.DESCRIBED_BY) {
+                RoXmlHttpRequest().invoke(it, this)
+            }
+        }
         collection.value.forEach {
-            console.log(it)
             RoXmlHttpRequest().invoke(it, this)
         }
     }
@@ -112,8 +125,10 @@ class CollectionAggregator(actionTitle: String, val parent: ObjectAggregator? =
     }
 
     private fun Property.descriptionLink(): Link? {
+        console.log("[CA.Property.descriptionLink]")
+        console.log(this)
         return links.find {
-            it.relation() == Relation.DESCRIBED_BY
+            it.relation() == Relation.ELEMENT_TYPE
         }
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt
index 19e02b4..3e4b776 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt
@@ -43,17 +43,22 @@ class ObjectAggregator(val actionTitle: String) : AggregatorWithLayout() {
     }
 
     override fun update(logEntry: LogEntry, subType: String) {
-        when (val obj = logEntry.getTransferObject()) {
-            is TObject -> handleObject(obj)
-            is ResultObject -> handleResultObject(obj)
-            is Property -> handleProperty(obj)
-            is Layout -> handleLayout(obj, dpm as ObjectDM)
-            is Grid -> handleGrid(obj)
-            is HttpError -> ErrorDialog(logEntry).open()
-            else -> log(logEntry)
+        if (logEntry.url != "") {  // le=="" -> invoked from CollectionAggregrator
+            when (val obj = logEntry.getTransferObject()) {
+                is TObject -> handleObject(obj)
+                is ResultObject -> handleResultObject(obj)
+                is Property -> handleProperty(obj)
+                is Layout -> handleLayout(obj, dpm as ObjectDM)
+                is Grid -> handleGrid(obj)
+                is HttpError -> ErrorDialog(logEntry).open()
+                else -> log(logEntry)
+            }
         }
 
         if (dpm.canBeDisplayed() && collectionsCanBeDisplayed()) {
+            collectionMap.forEach {
+                (dpm as ObjectDM).addCollection(it.key, it.value.dpm as CollectionDM)
+            }
             UiManager.openObjectView(this)
         }
     }
@@ -77,7 +82,7 @@ class ObjectAggregator(val actionTitle: String) : AggregatorWithLayout() {
         if (collectionMap.size == 0) {
             handleCollections(obj)
         }
-        invokeLayoutLink(obj)
+        invokeLayoutLink(obj, this)
     }
 
     private fun invokeInstance(obj: TObject) {
@@ -96,18 +101,17 @@ class ObjectAggregator(val actionTitle: String) : AggregatorWithLayout() {
     }
 
     private fun handleCollections(obj: TObject) {
-        console.log("[OA.handleCollections]")
         obj.getCollections().forEach {
             val key = it.id
             val aggregator = CollectionAggregator(key, this)
             collectionMap.put(key, aggregator)
-            console.log(key)
             val link = it.links.first()
             RoXmlHttpRequest().invoke(link, aggregator)
         }
     }
 
     private fun handleProperty(property: Property) {
+        console.log("[OA.handleProperty]")
         console.log(property)
         throw Throwable("[ObjectAggregator.handleProperty] not implemented yet")
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
index 0382118..89ea050 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
@@ -109,8 +109,8 @@ object EventStore {
     }
 
     fun cached(reSpec: ResourceSpecification): LogEntry {
-        val entry: LogEntry? = findBy(reSpec)
-        entry!!.setCached()
+        val entry: LogEntry = findBy(reSpec)!!
+        entry.setCached()
         updateStatus(entry)
         return entry
     }
@@ -186,7 +186,10 @@ object EventStore {
         val le = findBy(reSpec)
         return when {
             le == null -> false
-            le.hasResponse() && le.method == method && le.subType == reSpec.subType -> true
+            le.hasResponse() && le.method == method && le.subType == reSpec.subType -> {
+                le.setCached()
+                true
+            }
             le.isView() -> true
             else -> false
         }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
index dbd3a94..206ad37 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
@@ -22,7 +22,9 @@ import io.kvision.html.ButtonStyle
 import io.kvision.panel.SimplePanel
 import kotlinx.serialization.Contextual
 import kotlinx.serialization.Serializable
+import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
 import org.apache.isis.client.kroviz.core.aggregator.BaseAggregator
+import org.apache.isis.client.kroviz.core.aggregator.CollectionAggregator
 import org.apache.isis.client.kroviz.to.TransferObject
 import org.apache.isis.client.kroviz.ui.core.Constants
 import org.apache.isis.client.kroviz.ui.core.UiManager
@@ -32,11 +34,13 @@ import kotlin.js.Date
 // use color codes from css instead?
 enum class EventState(val id: String, val iconName: String, val style: ButtonStyle) {
     INITIAL("INITIAL", "fas fa-power-off", ButtonStyle.LIGHT),
-    RUNNING("RUNNING", "fas fa-play-circle", ButtonStyle.WARNING),
+    RUNNING("RUNNING", "fas fa-hourglass-start fa-rotate-90", ButtonStyle.WARNING),
     ERROR("ERROR", "fas fa-exclamation-circle", ButtonStyle.DANGER),
-    SUCCESS("SUCCESS", "fas fa-check-circle", ButtonStyle.SUCCESS),
+    SUCCESS_JS("SUCCESS_JS", "fab fa-js", ButtonStyle.SUCCESS),
+    SUCCESS_XML("SUCCESS_XML", "fas fa-code", ButtonStyle.SUCCESS),
+    SUCCESS_IMG("SUCCESS_IMG", "fas fa-image", ButtonStyle.SUCCESS),
     VIEW("VIEW", "fas fa-eye", ButtonStyle.INFO),
-    DUPLICATE("DUPLICATE", "fas fa-stop-circle", ButtonStyle.OUTLINESUCCESS),
+    DUPLICATE("DUPLICATE", "fas fa-copy", ButtonStyle.OUTLINESUCCESS),
     CLOSED("CLOSED", "fas fa-eye-slash", ButtonStyle.OUTLINEINFO),
     RELOAD("RELOAD", "fas fa-retweet", ButtonStyle.OUTLINEWARNING),
     MISSING("MISSING", "fas fa-bug", ButtonStyle.OUTLINEDANGER)
@@ -79,6 +83,7 @@ data class LogEntry(
 
     var cacheHits = 0
 
+    @Contextual
     val aggregators = mutableListOf<@Contextual BaseAggregator>()
     var nOfAggregators: Int = 0 // must be accessible (public) for LogEntryTable
 
@@ -122,7 +127,11 @@ data class LogEntry(
     fun setSuccess() {
         calculate()
         responseLength = response.length
-        state = EventState.SUCCESS
+        state = when {
+            url.startsWith(Constants.krokiUrl) -> EventState.SUCCESS_IMG
+            subType == Constants.subTypeXml -> EventState.SUCCESS_XML
+            else -> EventState.SUCCESS_JS
+        }
     }
 
     fun setCached() {
@@ -202,6 +211,9 @@ data class LogEntry(
 
     fun addAggregator(aggregator: BaseAggregator) {
         aggregators.add(aggregator)
+        if ((aggregators.size > 1) && ((aggregator is ActionDispatcher) || (aggregator is CollectionAggregator))) {
+            throw Throwable("[LogEntry.addAggregator] not implemented yet")
+        }
         nOfAggregators = aggregators.size
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/CollectionDM.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/CollectionDM.kt
index 7cddbed..e3eab03 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/CollectionDM.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/CollectionDM.kt
@@ -42,11 +42,13 @@ class CollectionDM(override val title: String) : DisplayModelWithLayout() {
 
     // canBeDisplayed checks for grid AND layout - for parented collection there seems to be no layout
     fun parentedCollectionCanBeDisplayed(): Boolean {
-        console.log("[CDM.parentedCollectionCanBeDisplayed]")
-        console.log(this)
-        val answer = grid != null
-        console.log(answer)
-        return answer
+        return when {
+            grid == null -> false
+            propertyDescriptionList.isEmpty() -> false
+            propertyLayoutList.isEmpty() -> false
+            propertyList.isEmpty() -> false
+            else -> true
+        }
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ObjectDM.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ObjectDM.kt
index 0d58a78..e1b0d96 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ObjectDM.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ObjectDM.kt
@@ -18,13 +18,14 @@
  */
 package org.apache.isis.client.kroviz.core.model
 
-import org.apache.isis.client.kroviz.core.event.EventStore
+import org.apache.isis.client.kroviz.core.event.EventStore.findBy
 import org.apache.isis.client.kroviz.core.event.ResourceSpecification
 import org.apache.isis.client.kroviz.core.event.RoXmlHttpRequest
 import org.apache.isis.client.kroviz.to.*
 
 class ObjectDM(override val title: String) : DisplayModelWithLayout() {
     var data: Exposer? = null
+    val collections = mutableMapOf<String, CollectionDM>()
     private var dirty: Boolean = false
 
     override fun canBeDisplayed(): Boolean {
@@ -39,6 +40,10 @@ class ObjectDM(override val title: String) : DisplayModelWithLayout() {
         dirty = value
     }
 
+    fun addCollection(key: String, value: CollectionDM) {
+        collections.put(key, value)
+    }
+
     override fun addData(obj: TransferObject) {
         (obj as TObject)
         val exo = Exposer(obj)
@@ -65,23 +70,22 @@ class ObjectDM(override val title: String) : DisplayModelWithLayout() {
             val href = getLink.href
             val reSpec = ResourceSpecification(href)
             //WATCHOUT this is sequence dependent: GET and PUT share the same URL - if called after PUTting, it may fail
-            val getLogEntry = EventStore.findBy(reSpec)!!
+            val getLogEntry = findBy(reSpec)!!
             getLogEntry.setReload()
 
             val putLink = Link(method = Method.PUT.operation, href = href)
-            val logEntry = EventStore.findBy(reSpec)
+            val logEntry = findBy(reSpec)
             val aggregator = logEntry?.getAggregator()!!
-            RoXmlHttpRequest().invoke(putLink, aggregator)
 
-            // now data should be reloaded - wait for invoking PUT?
+            RoXmlHttpRequest().invoke(putLink, aggregator)
+            // now data should be reloaded
             RoXmlHttpRequest().invoke(getLink, aggregator)
-            //refresh of display to be triggered?
         }
     }
 
     fun undo() {
         if (dirty) {
-            //TODO reset()
+            reset()
         }
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
index 2e86e98..13eb383 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
@@ -26,6 +26,10 @@ import org.apache.isis.client.kroviz.to.TransferObject
 class ActionHandler : BaseHandler() {
 
     override fun parse(response: String): TransferObject {
+        // due to some ambiguity in members, collection-description is accepted as action
+        if (response.contains("collection-description")) {
+            throw RuntimeException()
+        }
         return Json.decodeFromString(Action.serializer(), response)
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt
index c8ead08..c5e70b5 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt
@@ -30,7 +30,6 @@ class CollectionHandler : BaseHandler() {
     }
 
     override fun doHandle() {
-        //logEntry.addAggregator(ActionDispatcher())
         update()
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt
index 1380d0c..5b41f43 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt
@@ -103,6 +103,7 @@ enum class Relation(val type: String) {
     DOMAIN_TYPE("domain-type"),
     DOMAIN_TYPES("domain-types"),
     ELEMENT("element"),
+    ELEMENT_TYPE("element-type"),
     HELP("help"),               //IANA
     ICON("icon"),               //IANA
     INVOKE("invoke"),
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Col.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Col.kt
index 4d7f896..f6ec3ae 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Col.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Col.kt
@@ -22,10 +22,12 @@ import org.w3c.dom.Node
 import org.w3c.dom.asList
 
 class Col(node: Node) {
+    val rowList = mutableListOf<Row>()
     var domainObject: DomainObject? = null
     var actionList = mutableListOf<Action>()
     val tabGroupList = mutableListOf<TabGroup>()
     var fieldSetList = mutableListOf<FieldSet>()
+    var collectionList = mutableListOf<Collection>()
     var span: Int = 0
 
     init {
@@ -34,6 +36,12 @@ class Col(node: Node) {
 
         val nl = node.childNodes.asList()
 
+        val rl = nl.filter { it.nodeName.equals("bs3:row") }
+        for (n: Node in rl) {
+            val row = Row(n)
+            rowList.add(row)
+        }
+
         val doNodes = nl.filter { it.nodeName.equals("cpt:domainObject") }
         if (!doNodes.isEmpty()) {
             domainObject = DomainObject(doNodes.first())
@@ -56,6 +64,12 @@ class Col(node: Node) {
             val fs = FieldSet(n)
             fieldSetList.add(fs)
         }
+
+        val collNodes = nl.filter { it.nodeName.equals("cpt:collection") }
+        for (n: Node in collNodes) {
+            val c = Collection(n)
+            collectionList.add(c)
+        }
     }
 
     fun getPropertyList(): List<Property> {
@@ -66,6 +80,7 @@ class Col(node: Node) {
         tabGroupList.forEach { tg ->
             list.addAll(tg.getPropertyList())
         }
+        console.log("[CB.getPropertyList]")
         return list
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Collection.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Collection.kt
new file mode 100644
index 0000000..f66a1a4
--- /dev/null
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/bs3/Collection.kt
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.client.kroviz.to.bs3
+
+import org.w3c.dom.Node
+import org.w3c.dom.asList
+
+class Collection(node: Node) {
+    var bookmarking: String //BookmarkPolicy? = null use ENUM
+    var cssClass: String
+    var cssClassFa: String
+    var cssClassFaPosition: String
+    var hidden: String // USE ENUM Where? = null
+    var id: String
+    var position: String //USE ENUM Position? = null
+    var named = ""
+    var describedAs = ""
+
+    init {
+        val dyNode = node.asDynamic()
+        bookmarking = dyNode.getAttribute("bookmarking")
+        cssClass = dyNode.getAttribute("cssClass")
+        cssClassFa = dyNode.getAttribute("cssClassFa")
+        cssClassFaPosition = dyNode.getAttribute("cssClassFaPosition")
+        hidden = dyNode.getAttribute("hidden")
+        id = dyNode.getAttribute("id")
+        position = dyNode.getAttribute("position")
+        named = dyNode.getAttribute("named")
+        describedAs = dyNode.getAttribute("describedAs")
+
+        val nodeList = node.childNodes.asList()
+        val namedList = nodeList.filter { it.nodeName.equals("cpt:named") }
+        if (namedList.isNotEmpty()) {
+            val n = namedList.first()
+            named = n.textContent as String
+        }
+        val describedAsList = nodeList.filter { it.nodeName.equals("cpt:describedAs") }
+        if (describedAsList.isNotEmpty()) {
+            val n = describedAsList.first()
+            describedAs = n.textContent as String
+        }
+    }
+}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt
index 0a8bf9c..dddb061 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt
@@ -26,13 +26,12 @@ import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.to.bs3.Col
 import org.apache.isis.client.kroviz.ui.core.MenuFactory
 import org.apache.isis.client.kroviz.ui.core.RoDisplay
+import org.apache.isis.client.kroviz.ui.core.RoTable
 
 class ColBuilder : UiBuilder() {
 
     fun create(col: Col, tObject: TObject, dsp: RoDisplay): FlexPanel {
         val panel = buildPanel()
-        console.log("[CB.create] col:")
-        console.log(col)
 
         if (col.actionList.size > 0) {
             val menu = createMenu(tObject, dsp)
@@ -48,6 +47,22 @@ class ColBuilder : UiBuilder() {
             val fsPanel = FieldsetPanel(legend = fs.name).add(fsCpt)
             panel.add(fsPanel)
         }
+        for (row in col.rowList) {
+            val rowCpt = RowBuilder().create(row, tObject, dsp)
+            panel.add(rowCpt)
+        }
+        for (c in col.collectionList) {
+            console.log("[CB.create]")
+            console.log(c)
+            // analogous to UiManager.openCollectionView
+            val key = c.id  // entities
+            val objectDM = dsp.displayModel
+            val collectionDM = objectDM.collections.get(key)!!
+            console.log(collectionDM)
+            val tblCpt = RoTable(collectionDM)
+            panel.add(tblCpt)
+            collectionDM.isRendered = true
+        }
         return panel
     }
 
@@ -77,5 +92,4 @@ class ColBuilder : UiBuilder() {
         return panel
     }
 
-
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/FieldSetBuilder.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/FieldSetBuilder.kt
index 110f8ff..208c0eb 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/FieldSetBuilder.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/FieldSetBuilder.kt
@@ -42,11 +42,9 @@ class FieldSetBuilder {
             val member = members.firstOrNull() { it.id == label }
             if (member != null) {
                 val memberType = TypeMapper().forType(member.type!!)
-                console.log("[FSB.init]")
-                console.log(memberType)
                 val size = maxOf(1, p.multiLine)
                 val fi = FormItem(
-                        label = label,
+                        label = p.named,
                         type = memberType,
                         content = member.value?.content,
                         size = size,
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/FormPanelFactory.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/FormPanelFactory.kt
index 6181f8a..2c6b4d5 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/FormPanelFactory.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/FormPanelFactory.kt
@@ -44,7 +44,6 @@ import io.kvision.utils.perc
 import io.kvision.utils.px
 import org.apache.isis.client.kroviz.to.ValueType
 import org.apache.isis.client.kroviz.ui.dialog.Command
-import org.apache.isis.client.kroviz.ui.dialog.EventLogDetail
 import org.apache.isis.client.kroviz.ui.panel.SvgPanel
 import org.apache.isis.client.kroviz.utils.DateHelper
 import org.apache.isis.client.kroviz.utils.IconManager
@@ -91,13 +90,12 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() {
     }
 
     private fun createBoolean(fi: FormItem): Component {
-        if (fi.content == "true") {
-            return CheckBox(label = fi.label, value = true)
+        val value = fi.content
+        val bools = arrayOf("true", "false")
+        return when {
+            value in bools -> CheckBox(label = fi.label, value = (value == "true"))
+            else -> createText(fi)
         }
-        if (fi.content == "false") {
-            return CheckBox(label = fi.label, value = false)
-        }
-        return createText(fi)
     }
 
     private fun createTime(fi: FormItem): DateTime {
@@ -169,8 +167,7 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() {
 
     private fun createImage(fi: FormItem): VPanel {
         val panel = VPanel {
-            val fc = fi.content
-            when {
+            when (val fc = fi.content) {
                 fc is Image -> fc
                 fc is String -> {
                     // interpret as (file) URL and load locally
@@ -186,7 +183,8 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() {
             }
         }
         panel.height = auto
-        panel.width = 100.perc
+        panel.width = auto
+        panel.overflow = Overflow.AUTO
         return panel
     }
 
@@ -204,14 +202,16 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() {
             }
         }
         panel.height = auto
-        panel.width = 100.perc
+        panel.width = auto
+        panel.overflow = Overflow.SCROLL
         return panel
     }
 
     private fun createSvgMap(fi: FormItem): SvgPanel {
         val panel = SvgPanel()
-        panel.height = 100.perc
-        panel.width = 100.perc
+        panel.height = auto
+        panel.width = auto
+        panel.overflow = Overflow.SCROLL
         fi.callBack = panel
         return panel
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDisplay.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDisplay.kt
index 6b4f5b2..ecd6b7f 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDisplay.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDisplay.kt
@@ -34,8 +34,6 @@ class RoDisplay(val displayModel: ObjectDM) : Displayable, VPanel() {
     private var objectPanel: VPanel
 
     init {
-        console.log("[RD.init] tObject / grid")
-        console.log(displayModel)
         val model = displayModel.data!!
         val tObject: TObject = model.delegate
         val grid = displayModel.grid!!
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoView.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoView.kt
index a95cd4e..ed81588 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoView.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoView.kt
@@ -64,15 +64,13 @@ object RoView {
     }
 
     fun findActive(): SimplePanel? {
-        console.log("[RV.findActive]")
         val index = tabPanel.activeIndex
-        if (index > 0) {
+        return if (index > 0) {
             val tabs = tabPanel.getTabs()
-            val tab = tabs.get(index) as SimplePanel
-            console.log(tab)
-            return (tab)
+            tabs.get(index) as SimplePanel
+        } else {
+            null
         }
-        return null
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/UiManager.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/UiManager.kt
index c87c0ae..47c95cf 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/UiManager.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/UiManager.kt
@@ -166,8 +166,8 @@ object UiManager {
             it.relation() == Relation.OBJECT_LAYOUT
         }
         val reSpec = ResourceSpecification(layoutLink!!.href)
-        val logEntry = EventStore.findBy(reSpec)
-        logEntry!!.addAggregator(aggregator)
+        val logEntry = EventStore.findBy(reSpec)!!
+        logEntry.addAggregator(aggregator)
     }
 
     fun openDialog(panel: RoDialog) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
index 1ff4ee8..445b9af 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
@@ -39,7 +39,8 @@ class EventExportDialog() : Command() {
         EventStore.log.forEach { it ->
             val re = buildExportEvent(it)
             when (it.state) {
-                EventState.SUCCESS -> events.add(re)
+                EventState.SUCCESS_JS -> events.add(re)
+                EventState.SUCCESS_XML -> events.add(re)
                 EventState.ERROR -> events.add(re)
                 else -> {
                 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
index 4047871..3a1ccc9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
@@ -18,7 +18,10 @@
  */
 package org.apache.isis.client.kroviz.ui.dialog
 
+import org.apache.isis.client.kroviz.core.aggregator.CollectionAggregator
+import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.core.event.LogEntry
+import org.apache.isis.client.kroviz.core.event.ResourceSpecification
 import org.apache.isis.client.kroviz.to.ValueType
 import org.apache.isis.client.kroviz.to.bs3.Grid
 import org.apache.isis.client.kroviz.ui.core.Constants
@@ -29,29 +32,31 @@ import org.apache.isis.client.kroviz.ui.diagram.LayoutDiagram
 import org.apache.isis.client.kroviz.utils.Utils
 import org.apache.isis.client.kroviz.utils.XmlHelper
 
-class EventLogDetail(val logEntry: LogEntry) : Command() {
+class EventLogDetail(val logEntryFromTabulator: LogEntry) : Command() {
+    private var logEntry: LogEntry
+    init {
+        // For a yet unknown reason, aggregators are not transmitted via tabulator.
+        // As a WORKAROUND, we fetch the full blown LogEntry from the EventStore again.
+        val rs = ResourceSpecification(logEntryFromTabulator.title)
+        logEntry = EventStore.findBy(rs)!!
+    }
 
     private val LOG: String = "log"
+    private val OBJ: String = "obj"
 
-    fun open() {
-        val formItems = mutableListOf<FormItem>()
-
-        formItems.add(FormItem("Url", ValueType.TEXT, logEntry.url))
 
-        var responseStr = logEntry.response
-        if (logEntry.subType == Constants.subTypeJson) {
-            responseStr = Utils.format(responseStr)
+    fun open() {
+        val responseStr = if (logEntry.subType == Constants.subTypeJson) {
+            Utils.format(logEntry.response)
         } else {
-            responseStr = XmlHelper.formatXml(responseStr)
-        }
-        formItems.add(FormItem("Response", ValueType.TEXT_AREA, responseStr, 10))
-
-        var aggtStr = ""
-        logEntry.aggregators.forEach { it ->
-            aggtStr += it.toString()
+            XmlHelper.format(logEntry.response)
         }
-        formItems.add(FormItem("Aggregators", ValueType.TEXT_AREA, aggtStr, 5))
 
+        val formItems = mutableListOf<FormItem>()
+        formItems.add(FormItem("Url", ValueType.TEXT, logEntry.title))
+        formItems.add(FormItem("Response", ValueType.TEXT_AREA, responseStr, 10))
+        formItems.add(FormItem("Aggregators", ValueType.TEXT, content = logEntry.aggregators))
+        formItems.add(FormItem("Object Diagram", ValueType.BUTTON, null, callBack = this, callBackAction = OBJ))
         formItems.add(FormItem("Console", ValueType.BUTTON, null, callBack = this, callBackAction = LOG))
 
         RoDialog(
@@ -68,6 +73,9 @@ class EventLogDetail(val logEntry: LogEntry) : Command() {
             action == LOG -> {
                 console.log(logEntry)
             }
+            action == OBJ -> {
+                objectDiagram()
+            }
             else -> {
                 console.log(logEntry)
                 console.log("Action not defined yet: " + action)
@@ -75,6 +83,19 @@ class EventLogDetail(val logEntry: LogEntry) : Command() {
         }
     }
 
+    private fun objectDiagram() {
+        logEntry.aggregators.forEach {
+            console.log(it)
+            if (it is CollectionAggregator) {
+                val displayModel = it.dpm
+                val jsonStr = JSON.stringify(displayModel)
+                console.log(jsonStr)
+                val pumlCode = JsonDiagram.build(jsonStr)
+                DiagramDialog("Object Diagram", pumlCode).open()
+            }
+        }
+    }
+
     private fun defaultAction() {
         val str = logEntry.response
         val pumlCode = when {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt
index e22db8c..0a765a7 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt
@@ -49,7 +49,7 @@ object XmlHelper {
     }
 
     // Adopted from @link https://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript
-    fun formatXml(xml: String): String {
+    fun format(xml: String): String {
         var formatted = ""
         val reg = "/(>)(<)(/*)/g"
         var pad = 0
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ActionHandlerTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ActionHandlerTest.kt
index c7b6392..218951b 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ActionHandlerTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ActionHandlerTest.kt
@@ -19,22 +19,31 @@
 
 package org.apache.isis.client.kroviz.handler
 
-import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_STRINGS_INVOKE
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_STRINGS
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.COLLECTION_DESCRIPTION
+import org.apache.isis.client.kroviz.to.Action
 import kotlin.test.Test
-import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import kotlin.test.fail
 
 class ActionHandlerTest {
 
     @Test
-    fun testCanHandle() {
-        //given
-        val json = ACTIONS_STRINGS_INVOKE.str
-
-        //when
-        val actual = ActionHandler().canHandle(json)
+    fun testParse() {
+        val json = ACTIONS_STRINGS.str
+        val action = ActionHandler().parse(json)
+        assertTrue(action is Action)
+    }
 
-        //then
-        assertFalse(actual)
+    @Test
+    fun testParseSadCase() {
+        val json = COLLECTION_DESCRIPTION.str
+        try {
+            ActionHandler().parse(json)
+            fail("Exception expected")
+        } catch (re: RuntimeException) {
+            assertTrue(true)
+        }
     }
 
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTION_DESCRIPTION.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTION_DESCRIPTION.kt
new file mode 100644
index 0000000..5165d72
--- /dev/null
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTION_DESCRIPTION.kt
@@ -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.client.kroviz.snapshots.demo2_0_0
+
+import org.apache.isis.client.kroviz.snapshots.Response
+
+object COLLECTION_DESCRIPTION: Response(){
+    override val url = "http://localhost:8080/restful/domain-types/demo.JavaLangStrings/collections/entities"
+    override val str = """
+{
+  "id" : "entities",
+  "memberType" : "collection",
+  "links" : [ {
+    "rel" : "self",
+    "href" : "http://localhost:8080/restful/domain-types/demo.JavaLangStrings/collections/entities",
+    "method" : "GET",
+    "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/collection-description\""
+  }, {
+    "rel" : "up",
+    "href" : "http://localhost:8080/restful/domain-types/demo.JavaLangStrings",
+    "method" : "GET",
+    "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\""
+  }, {
+    "rel" : "urn:org.restfulobjects:rels/element-type",
+    "href" : "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity",
+    "method" : "GET",
+    "type" : "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\""
+  } ],
+  "extensions" : {
+    "friendlyName" : "Entities"
+  }
+}
+    """
+}
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/JAVA_LANG_STRING_ENTITY.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/JAVA_LANG_STRING_ENTITY.kt
new file mode 100644
index 0000000..5d40116
--- /dev/null
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/JAVA_LANG_STRING_ENTITY.kt
@@ -0,0 +1,262 @@
+/*
+ *  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.client.kroviz.snapshots.demo2_0_0
+
+import org.apache.isis.client.kroviz.snapshots.Response
+
+object JAVA_LANG_STRING_ENTITY : Response() {
+    override val url = "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity"
+    override val str = """
+{
+  "links": [
+    {
+      "rel": "self",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\""
+    },
+    {
+      "rel": "urn:org.apache.isis.restfulobjects:rels/layout",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/layout",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/layout-bs3\""
+    }
+  ],
+  "canonicalName": "demoapp.dom.types.javalang.strings.jdo.JavaLangStringJdo",
+  "members": {
+    "mixinProperty": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/mixinProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "description": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/description",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readWriteProperty": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readWriteProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readOnlyPropertyDerivedLabelPositionLeft": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readOnlyPropertyDerivedLabelPositionLeft",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readOnlyPropertyDerivedLabelPositionTop": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readOnlyPropertyDerivedLabelPositionTop",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readOnlyPropertyDerivedLabelPositionRight": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readOnlyPropertyDerivedLabelPositionRight",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readOnlyPropertyDerivedLabelPositionNone": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readOnlyPropertyDerivedLabelPositionNone",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "logicalTypeName": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/logicalTypeName",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "objectIdentifier": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/objectIdentifier",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "datanucleusVersionLong": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/datanucleusVersionLong",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "datanucleusVersionTimestamp": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/datanucleusVersionTimestamp",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readOnlyOptionalProperty": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readOnlyOptionalProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readWriteOptionalProperty": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readWriteOptionalProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "readOnlyProperty": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/readOnlyProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "sources": {
+      "rel": "urn:org.restfulobjects:rels/property",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/properties/sources",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/property-description\""
+    },
+    "actionReturningCollection": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/actionReturningCollection",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "updateReadOnlyOptionalProperty": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/updateReadOnlyOptionalProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "clearHints": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/clearHints",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "updateReadOnlyProperty": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/updateReadOnlyProperty",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "updateReadOnlyPropertyWithChoices": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/updateReadOnlyPropertyWithChoices",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "actionReturning": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/actionReturning",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "inspectMetamodel": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/inspectMetamodel",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "stopImpersonating": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/stopImpersonating",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "downloadLayoutXml": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/downloadLayoutXml",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "impersonateWithRoles": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/impersonateWithRoles",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "downloadMetamodelXml": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/downloadMetamodelXml",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "downloadJdoMetadata": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/downloadJdoMetadata",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "impersonate": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/impersonate",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "recentCommands": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/recentCommands",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "openRestApi": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/openRestApi",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    },
+    "rebuildMetamodel": {
+      "rel": "urn:org.restfulobjects:rels/action",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/actions/rebuildMetamodel",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+    }
+  },
+  "typeActions": {
+    "isSubtypeOf": {
+      "rel": "urn:org.restfulobjects:rels/invoke;typeaction=\"isSubtypeOf\"",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/type-actions/isSubtypeOf/invoke",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/type-action-result\"",
+      "arguments": {
+        "supertype": {
+          "href": null
+        }
+      }
+    },
+    "isSupertypeOf": {
+      "rel": "urn:org.restfulobjects:rels/invoke;typeaction=\"isSupertypeOf\"",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity/type-actions/isSupertypeOf/invoke",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/type-action-result\"",
+      "arguments": {
+        "subtype": {
+          "href": null
+        }
+      }
+    }
+  },
+  "extensions": {
+    "friendlyName": "Java Lang String Jdo",
+    "pluralName": "Java Lang String Jdos",
+    "isService": false
+  }
+}
+"""
+}
+
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/OBJECT_COLLECTION.kt
similarity index 98%
rename from incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt
rename to incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/OBJECT_COLLECTION.kt
index eac8bfc..958e292 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/OBJECT_COLLECTION.kt
@@ -21,7 +21,7 @@ package org.apache.isis.client.kroviz.snapshots.demo2_0_0
 
 import org.apache.isis.client.kroviz.snapshots.Response
 
-object COLLECTIONS_ENTITIES: Response(){
+object OBJECT_COLLECTION: Response(){
     override val url = "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/collections/entities"
     override val str = """
 {
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/Response2Handler.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/Response2Handler.kt
index 0bea8b0..12b161c 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/Response2Handler.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/Response2Handler.kt
@@ -28,7 +28,7 @@ object Response2Handler {
             ACTIONS_WHEREINTHEWORLD_INVOKE to TObjectHandler(),
             ACTIONS_TEXT_INVOKE to TObjectHandler(),
             ASSOCIATED_ACTION_OBJECT_LAYOUT to LayoutHandler(),
-            COLLECTIONS_ENTITIES to CollectionHandler(),
+            OBJECT_COLLECTION to CollectionHandler(),
             DOMAIN_TYPES_PROPERTY to PropertyHandler(),
             FILE_NODE to DomainTypeHandler(),
             HTTP_ERROR_405 to HttpErrorHandler(),
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/STRINGS_LAYOUT_XML.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/STRINGS_LAYOUT_XML.kt
new file mode 100644
index 0000000..18ecbeb
--- /dev/null
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/STRINGS_LAYOUT_XML.kt
@@ -0,0 +1,217 @@
+/*
+ *  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.client.kroviz.snapshots.demo2_0_0
+
+import org.apache.isis.client.kroviz.snapshots.Response
+
+object STRINGS_LAYOUT_XML: Response() {
+    override val url = "http://localhost:8080/restful/objects/demo.Tab/ADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8-CiAgICA8ZmllbGQxPmZpZWxkIDE8L2ZpZWxkMT4KICAgIDxmaWVsZDI-ZmllbGQgMjwvZmllbGQyPgogICAgPGhpZGRlbj5mYWxzZTwvaGlkZGVuPgo8L0RlbW8-Cg==/object-layout"
+    override val str = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<bs3:grid xmlns:cpt="http://isis.apache.org/applib/layout/component"
+          xmlns:lnk="http://isis.apache.org/applib/layout/links"
+          xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3">
+    <bs3:row>
+        <bs3:col span="10" unreferencedActions="true">
+            <cpt:domainObject>
+                <cpt:link>
+                    <lnk:rel>urn:org.restfulobjects:rels/element</lnk:rel>
+                    <lnk:method>GET</lnk:method>
+                    <lnk:href>
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=
+                    </lnk:href>
+                    <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object"</lnk:type>
+                </cpt:link>
+            </cpt:domainObject>
+            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-mask" cssClassFaPosition="LEFT" id="impersonate">
+                <cpt:named>Impersonate</cpt:named>
+                <cpt:link>
+                    <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                    <lnk:method>GET</lnk:method>
+                    <lnk:href>
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/impersonate
+                    </lnk:href>
+                    <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                </cpt:link>
+            </cpt:action>
+            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-mask" cssClassFaPosition="LEFT"
+                        id="impersonateWithRoles">
+                <cpt:named>Impersonate With Roles</cpt:named>
+                <cpt:link>
+                    <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                    <lnk:method>GET</lnk:method>
+                    <lnk:href>
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/impersonateWithRoles
+                    </lnk:href>
+                    <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                </cpt:link>
+            </cpt:action>
+            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-stop" cssClassFaPosition="LEFT"
+                        id="stopImpersonating">
+                <cpt:named>Stop Impersonating</cpt:named>
+                <cpt:link>
+                    <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                    <lnk:method>GET</lnk:method>
+                    <lnk:href>
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/stopImpersonating
+                    </lnk:href>
+                    <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                </cpt:link>
+            </cpt:action>
+        </bs3:col>
+        <bs3:col span="2">
+            <cpt:fieldSet name="" id="sources">
+                <cpt:property hidden="ALL_TABLES" id="sources" labelPosition="NONE">
+                    <cpt:named>Sources</cpt:named>
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/sources
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-property"
+                        </lnk:type>
+                    </cpt:link>
+                </cpt:property>
+            </cpt:fieldSet>
+        </bs3:col>
+    </bs3:row>
+    <bs3:row>
+        <bs3:col span="6">
+            <bs3:row>
+                <bs3:col span="12">
+                    <cpt:collection id="entities">
+                        <cpt:link>
+                            <lnk:rel>urn:org.restfulobjects:rels/collection</lnk:rel>
+                            <lnk:method>GET</lnk:method>
+                            <lnk:href>
+                                http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/collections/entities
+                            </lnk:href>
+                            <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-collection"
+                            </lnk:type>
+                        </cpt:link>
+                    </cpt:collection>
+                </bs3:col>
+                <bs3:col span="12">
+                    <cpt:action id="openViewModel">
+                        <cpt:link>
+                            <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                            <lnk:method>GET</lnk:method>
+                            <lnk:href>
+                                http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/openViewModel
+                            </lnk:href>
+                            <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"
+                            </lnk:type>
+                        </cpt:link>
+                    </cpt:action>
+                </bs3:col>
+            </bs3:row>
+            <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+        </bs3:col>
+        <bs3:col span="6">
+            <cpt:fieldSet name="Description" id="description">
+                <cpt:action id="clearHints" position="PANEL">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/clearHints
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="downloadLayoutXml" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/downloadLayoutXml
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="rebuildMetamodel" position="PANEL">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/rebuildMetamodel
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="downloadMetamodelXml" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/downloadMetamodelXml
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="inspectMetamodel" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/inspectMetamodel
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="recentCommands" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/recentCommands
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="openRestApi" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/openRestApi
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:property id="description">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/description
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-property"
+                        </lnk:type>
+                    </cpt:link>
+                </cpt:property>
+            </cpt:fieldSet>
+        </bs3:col>
+    </bs3:row>
+    <bs3:row>
+        <bs3:col span="12" unreferencedCollections="true"/>
+    </bs3:row>
+</bs3:grid>
+"""
+}
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json
index cb566cf..d14cb0f 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json
@@ -1,199 +1,45 @@
 {
+  "id": "entities",
+  "memberType": "collection",
   "links": [
     {
       "rel": "self",
-      "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStrings/collections/entities",
       "method": "GET",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
-      "title": "Malvern, UK"
+      "type": "application/json;profile=\\"
+      urn: org.restfulobjects
+      :
+      repr-types/collection-description
+      \
+      \
+      ""
     },
     {
-      "rel": "describedby",
-      "href": "http://localhost:8080/restful/domain-types/demo.CustomUiVm",
+      "rel": "up",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStrings",
       "method": "GET",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\""
+      "type": "application/json;profile=\\"
+      urn: org.restfulobjects
+      :
+      repr-types/domain-type
+      \
+      \
+      ""
     },
     {
-      "rel": "urn:org.apache.isis.restfulobjects:rels/object-layout",
-      "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/object-layout",
+      "rel": "urn:org.restfulobjects:rels/element-type",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStringEntity",
       "method": "GET",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-layout-bs3\""
-    },
-    {
-      "rel": "urn:org.apache.isis.restfulobjects:rels/object-icon",
-      "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/image",
-      "method": "GET",
-      "type": "image/png"
-    },
-    {
-      "rel": "urn:org.restfulobjects:rels/update",
-      "href": "http://localhost:8080/restful/objects/demo.CustomUiVm:PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K",
-      "method": "PUT",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
-      "arguments": {}
+      "type": "application/json;profile=\\"
+      urn: org.restfulobjects
+      :
+      repr-types/domain-type
+      \
+      \
+      ""
     }
   ],
   "extensions": {
-    "oid": "demo.CustomUiVm:PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K",
-    "isService": false,
-    "isPersistent": true
-  },
-  "title": "Malvern, UK",
-  "domainType": "demo.CustomUiVm",
-  "instanceId": "PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K",
-  "members": {
-    "address": {
-      "id": "address",
-      "memberType": "property",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;property=\"address\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/address",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\""
-        }
-      ],
-      "value": "Malvern, UK",
-      "extensions": {
-        "x-isis-format": "string"
-      },
-      "disabledReason": "Disabled"
-    },
-    "latitude": {
-      "id": "latitude",
-      "memberType": "property",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;property=\"latitude\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/latitude",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\""
-        }
-      ],
-      "value": "52.198944",
-      "extensions": {
-        "x-isis-format": "string"
-      },
-      "disabledReason": "Disabled"
-    },
-    "longitude": {
-      "id": "longitude",
-      "memberType": "property",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;property=\"longitude\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/longitude",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\""
-        }
-      ],
-      "value": "-2.2426571079130886",
-      "extensions": {
-        "x-isis-format": "string"
-      },
-      "disabledReason": "Disabled"
-    },
-    "zoom": {
-      "id": "zoom",
-      "memberType": "property",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;property=\"zoom\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/zoom",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\""
-        }
-      ],
-      "value": 14,
-      "format": "int",
-      "extensions": {
-        "x-isis-format": "int"
-      },
-      "disabledReason": "Disabled"
-    },
-    "clearHints": {
-      "id": "clearHints",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"clearHints\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/clearHints",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    },
-    "inspectMetamodel": {
-      "id": "inspectMetamodel",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"inspectMetamodel\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/inspectMetamodel",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    },
-    "downloadLayoutXml": {
-      "id": "downloadLayoutXml",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"downloadLayoutXml\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/downloadLayoutXml",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    },
-    "recentCommands": {
-      "id": "recentCommands",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"recentCommands\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/recentCommands",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    },
-    "rebuildMetamodel": {
-      "id": "rebuildMetamodel",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"rebuildMetamodel\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/rebuildMetamodel",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    },
-    "downloadMetamodelXml": {
-      "id": "downloadMetamodelXml",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"downloadMetamodelXml\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/downloadMetamodelXml",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    },
-    "openRestApi": {
-      "id": "openRestApi",
-      "memberType": "action",
-      "links": [
-        {
-          "rel": "urn:org.restfulobjects:rels/details;action=\"openRestApi\"",
-          "href": "http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/openRestApi",
-          "method": "GET",
-          "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
-        }
-      ]
-    }
+    "friendlyName": "Entities"
   }
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.xml b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.xml
index c50a196..aeff1c2 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.xml
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.xml
@@ -1,245 +1,191 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <bs3:grid xmlns:cpt="http://isis.apache.org/applib/layout/component"
           xmlns:lnk="http://isis.apache.org/applib/layout/links"
           xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3">
     <bs3:row>
-        <bs3:col span="12" unreferencedActions="true">
-            <cpt:domainObject bookmarking="AS_ROOT">
+        <bs3:col span="10" unreferencedActions="true">
+            <cpt:domainObject>
                 <cpt:link>
                     <lnk:rel>urn:org.restfulobjects:rels/element</lnk:rel>
                     <lnk:method>GET</lnk:method>
                     <lnk:href>
-                        http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=
                     </lnk:href>
                     <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object"</lnk:type>
                 </cpt:link>
             </cpt:domainObject>
-            <cpt:action bookmarking="NEVER" cssClassFa="far fa-fw fa-circle" cssClassFaPosition="LEFT" id="clearHints">
-                <cpt:named>Clear Hints</cpt:named>
+            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-mask" cssClassFaPosition="LEFT" id="impersonate">
+                <cpt:named>Impersonate</cpt:named>
                 <cpt:link>
                     <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
                     <lnk:method>GET</lnk:method>
                     <lnk:href>
-                        http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/clearHints
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/impersonate
                     </lnk:href>
                     <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
                 </cpt:link>
             </cpt:action>
-            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-bolt" cssClassFaPosition="LEFT" id="recentCommands">
-                <cpt:named>Recent Commands</cpt:named>
+            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-mask" cssClassFaPosition="LEFT"
+                        id="impersonateWithRoles">
+                <cpt:named>Impersonate With Roles</cpt:named>
                 <cpt:link>
                     <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
                     <lnk:method>GET</lnk:method>
                     <lnk:href>
-                        http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/recentCommands
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/impersonateWithRoles
                     </lnk:href>
                     <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
                 </cpt:link>
             </cpt:action>
+            <cpt:action bookmarking="NEVER" cssClassFa="fa fa-fw fa-stop" cssClassFaPosition="LEFT"
+                        id="stopImpersonating">
+                <cpt:named>Stop Impersonating</cpt:named>
+                <cpt:link>
+                    <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                    <lnk:method>GET</lnk:method>
+                    <lnk:href>
+                        http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/stopImpersonating
+                    </lnk:href>
+                    <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                </cpt:link>
+            </cpt:action>
+        </bs3:col>
+        <bs3:col span="2">
+            <cpt:fieldSet name="" id="sources">
+                <cpt:property hidden="ALL_TABLES" id="sources" labelPosition="NONE">
+                    <cpt:named>Sources</cpt:named>
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/sources
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-property"
+                        </lnk:type>
+                    </cpt:link>
+                </cpt:property>
+            </cpt:fieldSet>
         </bs3:col>
     </bs3:row>
     <bs3:row>
-        <bs3:col span="4">
+        <bs3:col span="6">
             <bs3:row>
                 <bs3:col span="12">
-                    <bs3:tabGroup>
-                        <bs3:tab name="Identity">
-                            <bs3:row>
-                                <bs3:col span="12">
-                                    <cpt:fieldSet name="Identity" id="identity"/>
-                                </bs3:col>
-                            </bs3:row>
-                        </bs3:tab>
-                        <bs3:tab name="Other">
-                            <bs3:row>
-                                <bs3:col span="12">
-                                    <cpt:fieldSet name="Other" id="other" unreferencedProperties="true">
-                                        <cpt:property id="address" labelPosition="LEFT" typicalLength="25">
-                                            <cpt:named>Address</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/address
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                        <cpt:property id="latitude" labelPosition="LEFT" typicalLength="25">
-                                            <cpt:named>Latitude</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/latitude
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                        <cpt:property id="longitude" labelPosition="LEFT" typicalLength="25">
-                                            <cpt:named>Longitude</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/longitude
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                        <cpt:property id="zoom" labelPosition="LEFT" typicalLength="9">
-                                            <cpt:named>Zoom</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/zoom
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                        <cpt:property hidden="ALL_TABLES" id="description" labelPosition="NONE">
-                                            <cpt:named>Description</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/description
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                        <cpt:property hidden="ALL_TABLES" id="sources" labelPosition="NONE">
-                                            <cpt:named>Sources</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/sources
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                    </cpt:fieldSet>
-                                </bs3:col>
-                            </bs3:row>
-                        </bs3:tab>
-                        <bs3:tab name="Metadata">
-                            <bs3:row>
-                                <bs3:col span="12">
-                                    <cpt:fieldSet name="Metadata" id="metadata">
-                                        <cpt:action id="downloadLayoutXml" position="PANEL_DROPDOWN">
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/downloadLayoutXml
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-action"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:action>
-                                        <cpt:action id="downloadMetamodelXml" position="PANEL_DROPDOWN">
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/downloadMetamodelXml
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-action"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:action>
-                                        <cpt:action id="inspectMetamodel" position="PANEL_DROPDOWN">
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/inspectMetamodel
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-action"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:action>
-                                        <cpt:action id="openRestApi" position="PANEL_DROPDOWN">
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/openRestApi
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-action"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:action>
-                                        <cpt:action id="rebuildMetamodel" position="PANEL_DROPDOWN">
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/actions/rebuildMetamodel
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-action"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:action>
-                                        <cpt:property hidden="ALL_TABLES" id="objectType" typicalLength="25">
-                                            <cpt:named>Object Type</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/objectType
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                        <cpt:property hidden="ALL_TABLES" id="objectIdentifier" typicalLength="25">
-                                            <cpt:named>Object Identifier</cpt:named>
-                                            <cpt:link>
-                                                <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
-                                                <lnk:method>GET</lnk:method>
-                                                <lnk:href>
-                                                    http://localhost:8080/restful/objects/demo.CustomUiVm/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPGRlbW8uQ3VzdG9tVWlWbT4KICAgIDxhZGRyZXNzPk1hbHZlcm4sIFVLPC9hZGRyZXNzPgogICAgPGxhdGl0dWRlPjUyLjE5ODk0NDwvbGF0aXR1ZGU-CiAgICA8bG9uZ2l0dWRlPi0yLjI0MjY1NzEwNzkxMzA4ODY8L2xvbmdpdHVkZT4KICAgIDx6b29tPjE0PC96b29tPgo8L2RlbW8uQ3VzdG9tVWlWbT4K/properties/objectIdentifier
-                                                </lnk:href>
-                                                <lnk:type>
-                                                    application/json;profile="urn:org.restfulobjects:repr-types/object-property"
-                                                </lnk:type>
-                                            </cpt:link>
-                                        </cpt:property>
-                                    </cpt:fieldSet>
-                                </bs3:col>
-                            </bs3:row>
-                        </bs3:tab>
-                    </bs3:tabGroup>
+                    <cpt:collection id="entities">
+                        <cpt:link>
+                            <lnk:rel>urn:org.restfulobjects:rels/collection</lnk:rel>
+                            <lnk:method>GET</lnk:method>
+                            <lnk:href>
+                                http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/collections/entities
+                            </lnk:href>
+                            <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-collection"
+                            </lnk:type>
+                        </cpt:link>
+                    </cpt:collection>
                 </bs3:col>
-            </bs3:row>
-            <bs3:row>
                 <bs3:col span="12">
-                    <cpt:fieldSet name="Details" id="details"/>
+                    <cpt:action id="openViewModel">
+                        <cpt:link>
+                            <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                            <lnk:method>GET</lnk:method>
+                            <lnk:href>
+                                http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/openViewModel
+                            </lnk:href>
+                            <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"
+                            </lnk:type>
+                        </cpt:link>
+                    </cpt:action>
                 </bs3:col>
             </bs3:row>
+            <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
         </bs3:col>
-        <bs3:col span="8">
-            <bs3:tabGroup unreferencedCollections="true"/>
+        <bs3:col span="6">
+            <cpt:fieldSet name="Description" id="description">
+                <cpt:action id="clearHints" position="PANEL">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/clearHints
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="downloadLayoutXml" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/downloadLayoutXml
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="rebuildMetamodel" position="PANEL">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/rebuildMetamodel
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="downloadMetamodelXml" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/downloadMetamodelXml
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="inspectMetamodel" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/inspectMetamodel
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="recentCommands" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/recentCommands
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:action id="openRestApi" position="PANEL_DROPDOWN">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/openRestApi
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-action"</lnk:type>
+                    </cpt:link>
+                </cpt:action>
+                <cpt:property id="description">
+                    <cpt:link>
+                        <lnk:rel>urn:org.restfulobjects:rels/property</lnk:rel>
+                        <lnk:method>GET</lnk:method>
+                        <lnk:href>
+                            http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/description
+                        </lnk:href>
+                        <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object-property"
+                        </lnk:type>
+                    </cpt:link>
+                </cpt:property>
+            </cpt:fieldSet>
         </bs3:col>
     </bs3:row>
+    <bs3:row>
+        <bs3:col span="12" unreferencedCollections="true"/>
+    </bs3:row>
 </bs3:grid>
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt
index 58f68b3..12c01f7 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt
@@ -20,7 +20,7 @@ package org.apache.isis.client.kroviz.to
 
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.handler.CollectionHandler
-import org.apache.isis.client.kroviz.snapshots.demo2_0_0.COLLECTIONS_ENTITIES
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.OBJECT_COLLECTION
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
@@ -29,7 +29,7 @@ class CollectionTest : IntegrationTest() {
     @Test
     fun testParse() {
         //given
-        val jsonStr = COLLECTIONS_ENTITIES.str
+        val jsonStr = OBJECT_COLLECTION.str
         //when
         val collection = CollectionHandler().parse(jsonStr) as Collection
         //then
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt
index ec5bdd1..50f7d9c 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt
@@ -20,6 +20,7 @@ package org.apache.isis.client.kroviz.to
 
 import org.apache.isis.client.kroviz.handler.DomainTypeHandler
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.FILE_NODE
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.JAVA_LANG_STRING_ENTITY
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
@@ -27,6 +28,16 @@ import kotlin.test.assertNotNull
 class DomainTypeTest {
 
     @Test
+    fun testParseJavaLangStringEntity() {
+        //given
+        val jsonStr = JAVA_LANG_STRING_ENTITY.str
+        //when
+        val to = DomainTypeHandler().parse(jsonStr) as DomainType
+        //then
+        assertEquals("Java Lang String Jdo", to.extensions.friendlyName)
+    }
+
+    @Test
     fun testParseFileNode() {
         // given
         val jsonStr = FILE_NODE.str
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
index d4f3bc2..025206a 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
@@ -19,9 +19,7 @@
 package org.apache.isis.client.kroviz.to
 
 import kotlinx.serialization.json.Json
-import org.apache.isis.client.kroviz.handler.*
-import org.apache.isis.client.kroviz.snapshots.demo2_0_0.*
-import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.RESTFUL
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.Response2Handler
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertTrue
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt
index 98755dd..2511fd2 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt
@@ -20,6 +20,7 @@ package org.apache.isis.client.kroviz.to
 
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.handler.MemberHandler
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.COLLECTION_DESCRIPTION
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.FR_PROPERTY_DESCRIPTION
 import kotlin.test.Test
 import kotlin.test.assertEquals
@@ -75,6 +76,14 @@ class MemberTest() {
         assertEquals("ResultListResult class", extensions.friendlyName)
     }
 
+    @Test
+    fun testParseCollection() {
+        val m = MemberHandler().parse(COLLECTION_DESCRIPTION.str) as Member
+        val extensions: Extensions? = m.extensions
+        assertNotNull(extensions)
+        assertEquals("Entities", extensions.friendlyName)
+    }
+
     private fun parse(jsonStr: String): Member {
         return Json.decodeFromString(Member.serializer(), jsonStr)
     }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/bs3/LayoutXmlTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/bs3/LayoutXmlTest.kt
index 1c9764d..8d51f77 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/bs3/LayoutXmlTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/bs3/LayoutXmlTest.kt
@@ -19,6 +19,7 @@
 package org.apache.isis.client.kroviz.to.bs3
 
 import org.apache.isis.client.kroviz.handler.LayoutXmlHandler
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.STRINGS_LAYOUT_XML
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.TAB_LAYOUT_XML
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO_LAYOUT_XML
 import kotlin.test.Test
@@ -26,7 +27,35 @@ import kotlin.test.assertEquals
 
 class LayoutXmlTest {
 
-   @Test
+    @Test
+    fun testDemoStringGrid() {
+        //given
+        val xmlStr = STRINGS_LAYOUT_XML.str
+        //when
+        val grid = LayoutXmlHandler().parse(xmlStr) as Grid
+        // then
+        assertEquals(3, grid.rows.size, message = "grid.rows.size")    //1
+
+        val primaryRow = grid.rows[1]
+        assertEquals(2, primaryRow.colList.size, message = "primaryRow.colList.size")    //2
+
+        val primaryCol = primaryRow.colList[0]
+        assertEquals(1, primaryCol.rowList.size, message = "primaryCol.rowList.size")    //3
+
+        val secondaryRow = primaryCol.rowList[0]
+        assertEquals(2, secondaryRow.colList.size, message = "secondaryRow.colList.size") //4
+
+        val secondaryCol = secondaryRow.colList[0]
+        assertEquals("12", secondaryCol.span, message = "secondaryCol.span") //5
+
+        val collectionList = secondaryCol.collectionList
+        assertEquals(1, collectionList.size, message = "collectionList.size") //6
+
+        val collection = collectionList[0]
+        assertEquals("entities", collection.id, message = "collection.id")
+    }
+
+    @Test
     fun testDemoTabGrid() {
         //given
         val xmlStr = TAB_LAYOUT_XML.str
@@ -35,7 +64,7 @@ class LayoutXmlTest {
         // then
         console.log("[LXT.testDemoTabGrid]")
         console.log(grid)
-       console.log("rows: ", grid.rows.size)
+        console.log("rows: ", grid.rows.size)
 //        assertEquals(2, grid.rows.size)    //1
     }