You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by rm...@apache.org on 2013/03/24 18:45:17 UTC

[20/24] Restructuring Scimpi to remove dependencies and enable easier testing.

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/AbstractConditionalBlock.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/AbstractConditionalBlock.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/AbstractConditionalBlock.java
new file mode 100644
index 0000000..4f9ec0d
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/AbstractConditionalBlock.java
@@ -0,0 +1,563 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.control;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.typeof.TypeOfFacet;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionContainer.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public abstract class AbstractConditionalBlock extends AbstractElementProcessor {
+
+    private static Map<String, Test> tests = new HashMap<String, Test>();
+
+    static {
+        addNormal(new TestHasRole(), "has-role");
+        addNegated(new TestHasRole(), "has-not-role");
+
+        addNormal(new TestVariableExists(), "variable-exists");
+        addNegated(new TestVariableExists(), "variable-missing");
+        addNormal(new TestVariableTrue(), "variable-true");
+        addNegated(new TestVariableTrue(), "variable-false");
+
+        addNormal(new TestObjectPersistent(), "object-persistent");
+        addNegated(new TestObjectPersistent(), "object-transient");
+        addNormal(new TestObjectType(), "object-type");
+        /*
+         * addNormal(new TestObjectIs(), "object-is"); addNegated(new
+         * TestObjectIs(), "object-is-not"); addNormal(new TestObjectType(),
+         * "object-type"); addNormal(new TestObjectType(),
+         * "object-title-equals"); addNegated(new TestObjectType(),
+         * "object-title-not-equals"); addNormal(new TestObjectType(),
+         * "object-title-contains"); addNegated(new TestObjectType(),
+         * "object-title-not-contains");
+         */
+        addNormal(new TestCollectionFull(), "collection-full");
+        addNegated(new TestCollectionFull(), "collection-empty");
+        addNormal(new TestCollectionType(), "collection-type");
+        // addNormal(new TestCollectionSize(), "collection-size-equal");
+        // addNormal(new TestCollectionSize(), "collection-size-less-than");
+        // addNormal(new TestCollectionSize(), "collection-size-greater-than");
+
+        addNormal(new TestFieldValue(), "test-field");
+        addNegated(new TestFieldValue(), "test-field");
+           
+        addNormal(new TestFieldExists(), "field-exists");
+        addNegated(new TestFieldExists(), "field-missing");
+        addNormal(new TestFieldVisible(), "field-visible");
+        addNegated(new TestFieldVisible(), "field-hidden");
+        addNormal(new TestFieldEditable(), "field-editable");
+        addNegated(new TestFieldEditable(), "field-not-editable");
+        addNormal(new TestFieldType(), "field-type");
+        addNormal(new TestFieldSet(), "field-set");
+        addNegated(new TestFieldSet(), "field-empty");
+        // empty/set etc
+
+        addNormal(new TestMethodExists(), "method-exists");
+        addNegated(new TestMethodExists(), "method-missing");
+        addNormal(new TestMethodVisible(), "method-visible");
+        addNegated(new TestMethodVisible(), "method-hidden");
+        addNormal(new TestMethodUseable(), "method-useable");
+        addNegated(new TestMethodUseable(), "method-not-useable");
+
+    }
+
+    private static void addNegated(final Test test, final String name) {
+        test.name = name;
+        test.negateResult = true;
+        tests.put(name, test);
+    }
+
+    private static void addNormal(final Test test, final String name) {
+        test.name = name;
+        tests.put(name, test);
+    }
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String id = templateProcessor.getOptionalProperty(OBJECT);
+
+        boolean checkMade = false;
+        boolean allConditionsMet = true;
+
+        final String[] propertyNames = templateProcessor.getAttributes().getPropertyNames(new String[] { "object", "collection" });
+        for (final String propertyName : propertyNames) {
+            boolean result;
+            if (propertyName.equals("set")) {
+                result = templateProcessor.isPropertySet("set");
+            } else {
+                final Test test = tests.get(propertyName);
+                if (test == null) {
+                    throw new ScimpiException("No such test: " + propertyName);
+                }
+                final String attributeValue = templateProcessor.getOptionalProperty(propertyName, false);
+                result = test.test(templateProcessor, attributeValue, id);
+                if (test.negateResult) {
+                    result = !result;
+                }
+            }
+            checkMade = true;
+            allConditionsMet &= result;
+        }
+
+        /*
+         * 
+         * // Check variables if
+         * (request.isPropertySpecified("variable-exists")) { boolean
+         * valuePresent = request.isPropertySet("variable-exists"); checkMade =
+         * true; allConditionsMet &= valuePresent; }
+         * 
+         * String variable = request.getOptionalProperty("variable-true"); if
+         * (variable != null) { String value = (String)
+         * request.getContext().getVariable(variable); checkMade = true;
+         * allConditionsMet &= Attributes.isTrue(value); }
+         * 
+         * variable = request.getOptionalProperty("variable-equals"); if
+         * (variable != null) { String value = (String)
+         * request.getContext().getVariable(variable); checkMade = true;
+         * allConditionsMet &= variable.equals(value); }
+         */
+        // Check Object
+
+        /*
+         * // Check Collection String collection =
+         * request.getOptionalProperty("collection-" + TYPE); if (collection !=
+         * null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), collection); Class<?>
+         * cls = forClass(request); TypeOfFacet facet =
+         * object.getSpecification().getFacet(TypeOfFacet.class); boolean
+         * hasType = object != null && (cls == null ||
+         * cls.isAssignableFrom(facet.value())); checkMade = true;
+         * allConditionsMet &= hasType;; }
+         * 
+         * collection = request.getOptionalProperty("collection-" + "empty"); if
+         * (collection != null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); CollectionFacet
+         * facet = object.getSpecification().getFacet(CollectionFacet.class);
+         * boolean isEmpty = facet != null && facet.size(object) == 0;
+         * processTags(isEmpty, request); allConditionsMet &= isEmpty; }
+         */
+
+        // Check Methods
+        /*
+         * String method = request.getOptionalProperty(METHOD + "-exists"); if
+         * (method != null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); List<? extends
+         * ObjectAction> objectActions =
+         * object.getSpecification().getObjectActions(ActionType.USER); boolean
+         * methodExists = false; for (ObjectAction objectAssociation :
+         * objectActions) { if (objectAssociation.getId().equals(method)) {
+         * methodExists = true; break; } } checkMade = true; allConditionsMet &=
+         * methodExists; }
+         * 
+         * method = request.getOptionalProperty(METHOD + "-visible"); if (method
+         * != null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); // TODO needs to
+         * work irrespective of parameters ObjectAction objectAction =
+         * object.getSpecification().getObjectAction(ActionType.USER, method,
+         * ObjectSpecification.EMPTY_LIST); Consent visible =
+         * objectAction.isVisible(IsisContext.getAuthenticationSession(),
+         * object); checkMade = true; allConditionsMet &= visible.isAllowed(); }
+         * 
+         * method = request.getOptionalProperty(METHOD + "-usable"); if (method
+         * != null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); // TODO needs to
+         * work irrespective of parameters ObjectAction objectAction =
+         * object.getSpecification().getObjectAction(ActionType.USER, method,
+         * ObjectSpecification.EMPTY_LIST); Consent usable =
+         * objectAction.isUsable(IsisContext.getAuthenticationSession(),
+         * object); checkMade = true; allConditionsMet &= usable.isAllowed(); }
+         * 
+         * 
+         * // Check Fields String field = request.getOptionalProperty(FIELD +
+         * "-exists"); if (field != null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); List<? extends
+         * ObjectAssociation> objectFields =
+         * object.getSpecification().getAssociations(); boolean fieldExists =
+         * false; for (ObjectAssociation objectAssociation : objectFields) { if
+         * (objectAssociation.getId().equals(field)) { fieldExists = true;
+         * break; } } checkMade = true; allConditionsMet &= fieldExists; }
+         * 
+         * field = request.getOptionalProperty(FIELD + "-visible"); if (field !=
+         * null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); ObjectAssociation
+         * objectField = object.getSpecification().getAssociation(field);
+         * Consent visible =
+         * objectField.isVisible(IsisContext.getAuthenticationSession(),
+         * object); checkMade = true; allConditionsMet &= visible.isAllowed(); }
+         * 
+         * field = request.getOptionalProperty(FIELD + "-editable"); if (field
+         * != null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); ObjectAssociation
+         * objectField = object.getSpecification().getAssociation(field);
+         * Consent usable =
+         * objectField.isUsable(IsisContext.getAuthenticationSession(), object);
+         * checkMade = true; allConditionsMet &= usable.isAllowed(); }
+         * 
+         * field = request.getOptionalProperty(FIELD + "-empty"); if (field !=
+         * null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); ObjectAssociation
+         * objectField = object.getSpecification().getAssociation(field);
+         * IsisContext.getPersistenceSession().resolveField(object,
+         * objectField); ObjectAdapter fld = objectField.get(object); if (fld ==
+         * null) { checkMade = true; allConditionsMet &= true; } else {
+         * CollectionFacet facet =
+         * fld.getSpecification().getFacet(CollectionFacet.class); boolean
+         * isEmpty = facet != null && facet.size(fld) == 0; processTags(isEmpty,
+         * request); allConditionsMet &= isEmpty; } }
+         * 
+         * field = request.getOptionalProperty(FIELD + "-set"); if (field !=
+         * null) { ObjectAdapter object =
+         * MethodsUtils.findObject(request.getContext(), id); ObjectAssociation
+         * objectField = object.getSpecification().getAssociation(field);
+         * IsisContext.getPersistenceSession().resolveField(object,
+         * objectField); ObjectAdapter fld = objectField.get(object); if (fld ==
+         * null) { throw new ScimpiException("No object for field-set " +
+         * field); } Object fieldValue = fld.getObject(); if (fieldValue
+         * instanceof Boolean) { checkMade = true; allConditionsMet &=
+         * ((Boolean) fieldValue).booleanValue(); } else { checkMade = true;
+         * allConditionsMet &= true; } }
+         */
+
+        // Check User
+        /*
+         * String hasRole = request.getOptionalProperty("has-role"); if (hasRole
+         * != null) { AuthenticationSession session =
+         * IsisContext.getSession().getAuthenticationSession(); List<String>
+         * roles = session.getRoles(); boolean hasMatchingRole = false; for
+         * (String role : roles) { if (role.equals(hasRole.trim())) {
+         * hasMatchingRole = true; break; } } checkMade = true; allConditionsMet
+         * &= hasMatchingRole; }
+         */
+
+        final String persistent = templateProcessor.getOptionalProperty("persistent");
+        if (persistent != null) {
+            final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(persistent);
+            checkMade = true;
+            allConditionsMet &= object.representsPersistent();
+        }
+        /*
+         * String type = request.getOptionalProperty(TYPE); if (type != null) {
+         * ObjectAdapter object = MethodsUtils.findObject(request.getContext(),
+         * id); Class<?> cls = forClass(request); boolean hasType = object !=
+         * null && (cls == null ||
+         * cls.isAssignableFrom(object.getObject().getClass())); checkMade =
+         * true; allConditionsMet &= hasType;; }
+         */
+        if (templateProcessor.isPropertySpecified("empty")) {
+            if (templateProcessor.isPropertySet("empty")) {
+                final String collection = templateProcessor.getOptionalProperty("empty");
+                if (collection != null) {
+                    final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(collection);
+                    final CollectionFacet facet = object.getSpecification().getFacet(CollectionFacet.class);
+                    checkMade = true;
+                    allConditionsMet &= facet.size(object) == 0;
+                }
+            } else {
+                checkMade = true;
+                allConditionsMet &= true;
+            }
+        }
+
+        if (templateProcessor.isPropertySpecified("set")) {
+            final boolean valuePresent = templateProcessor.isPropertySet("set");
+            checkMade = true;
+            allConditionsMet &= valuePresent;
+        }
+
+        if (checkMade) {
+            processTags(allConditionsMet, templateProcessor);
+        } else {
+            throw new ScimpiException("No condition in " + getName());
+        }
+    }
+
+    protected abstract void processTags(boolean isSet, TemplateProcessor templateProcessor);
+
+}
+
+abstract class Test {
+    String name;
+    boolean negateResult;
+
+    abstract boolean test(TemplateProcessor templateProcessor, String attributeName, String targetId);
+
+    protected Class<?> forClass(final String className) {
+        Class<?> cls = null;
+        if (className != null) {
+            try {
+                cls = Class.forName(className);
+            } catch (final ClassNotFoundException e) {
+                throw new ScimpiException("No class for " + className, e);
+            }
+        }
+        return cls;
+    }
+    
+    protected ObjectAction findMethod(final String attributeName, final ObjectAdapter object) {
+        final ObjectAction objectAction = object.getSpecification().getObjectAction(ActionType.USER, attributeName, ObjectSpecification.EMPTY_LIST);
+        if (objectAction == null) {
+            throw new ScimpiException("No such method found in " + object.getSpecification().getIdentifier().getClassName() + " : " + attributeName);
+        }
+        return objectAction;
+    }
+
+    protected ObjectAssociation findProperty(final String attributeName, final ObjectAdapter object) {
+        final ObjectAssociation objectField = object.getSpecification().getAssociation(attributeName);
+        if (objectField == null) {
+            throw new ScimpiException("No such property found in " + object.getSpecification().getIdentifier().getClassName() + ": " + attributeName);
+        }
+        return objectField;
+    }
+
+}
+
+class TestVariableExists extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        Object variable = templateProcessor.getContext().getVariable(attributeName);
+        if (variable instanceof String && ((String) variable).equals("")) {
+            return false;
+        }
+        return variable != null;
+    }
+}
+
+class TestVariableTrue extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final Object variable = templateProcessor.getContext().getVariable(attributeName);
+        final Boolean value = variable instanceof Boolean ? (Boolean) variable : Boolean.valueOf((String) variable);
+        return value != null && value.booleanValue();
+    }
+}
+
+class TestObjectPersistent extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(attributeName);
+        return object.representsPersistent();
+    }
+}
+
+class TestObjectType extends TestObjectPersistent {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final Class<?> cls = forClass(attributeName);
+        final boolean hasType = object != null && (cls == null || cls.isAssignableFrom(object.getObject().getClass()));
+        return hasType;
+    }
+}
+
+class TestCollectionType extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final Class<?> cls = forClass(attributeName);
+        final TypeOfFacet facet = object.getSpecification().getFacet(TypeOfFacet.class);
+        final boolean hasType = object != null && (cls == null || cls.isAssignableFrom(facet.value()));
+        return hasType;
+    }
+}
+
+class TestCollectionFull extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), attributeName);
+        final CollectionFacet facet = object.getSpecification().getFacet(CollectionFacet.class);
+        final boolean isEmpty = facet != null && facet.size(object) == 0;
+        return !isEmpty;
+    }
+}
+
+class TestMethodExists extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final List<? extends ObjectAction> objectActions = object.getSpecification().getObjectActions(ActionType.USER, Contributed.INCLUDED);
+        boolean methodExists = false;
+        for (final ObjectAction objectAssociation : objectActions) {
+            if (objectAssociation.getId().equals(attributeName)) {
+                methodExists = true;
+                break;
+            }
+        }
+        return methodExists;
+    }
+}
+
+class TestMethodVisible extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        // TODO needs to work irrespective of parameters
+        final ObjectAction objectAction = findMethod(attributeName, object);
+        final Consent visible = objectAction.isVisible(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE);
+        return visible.isAllowed();
+    }
+}
+
+class TestMethodUseable extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        // TODO needs to work irrespective of parameters
+        final ObjectAction objectAction = findMethod(attributeName, object);
+        final Consent usable = objectAction.isUsable(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE);
+        return usable.isAllowed();
+    }
+}
+
+class TestFieldExists extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final List<? extends ObjectAssociation> objectFields = object.getSpecification().getAssociations();
+        boolean fieldExists = false;
+        for (final ObjectAssociation objectAssociation : objectFields) {
+            if (objectAssociation.getId().equals(attributeName)) {
+                fieldExists = true;
+                break;
+            }
+        }
+        return fieldExists;
+    }
+}
+
+class TestFieldVisible extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final ObjectAssociation objectField = findProperty(attributeName, object);
+        final Consent visible = objectField.isVisible(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE);
+        return visible.isAllowed();
+    }
+}
+
+class TestFieldEditable extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final ObjectAssociation objectField = findProperty(attributeName, object);
+        final Consent usable = objectField.isUsable(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE);
+        return usable.isAllowed();
+    }
+}
+
+class TestFieldType extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final Class<?> cls = forClass(attributeName);
+        final boolean hasType = object != null && (cls == null || cls.isAssignableFrom(object.getObject().getClass()));
+        return hasType;
+    }
+}
+
+class TestFieldSet extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final ObjectAssociation objectField = findProperty(attributeName, object);
+        IsisContext.getPersistenceSession().resolveField(object, objectField);
+        final ObjectAdapter fld = objectField.get(object);
+        if (fld != null) {
+            final Object fieldValue = fld.getObject();
+            if (fieldValue instanceof Boolean) {
+                return ((Boolean) fieldValue).booleanValue();
+            } else if (fld.getSpecification().containsFacet(CollectionFacet.class)) {
+                final CollectionFacet facet = fld.getSpecification().getFacet(CollectionFacet.class);
+                final boolean isEmpty = facet != null && facet.size(fld) == 0;
+                return !isEmpty;
+            } else {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
+class TestFieldValue extends Test {
+    @Override
+    boolean test(TemplateProcessor templateProcessor, String attributeName, String targetId) {
+        int pos = attributeName.indexOf("==");
+        // TODO test for other comparators
+        // TODO fail properly if none found
+        String fieldName = attributeName.substring(0, pos);
+        String fieldValue = attributeName.substring(pos + 2);
+        
+        final ObjectAdapter object = MethodsUtils.findObject(templateProcessor.getContext(), targetId);
+        final ObjectAssociation objectField = findProperty(fieldName, object);
+        IsisContext.getPersistenceSession().resolveField(object, objectField);
+        final ObjectAdapter fld = objectField.get(object);
+        
+        // TODO test for reference or value
+        final ObjectAdapter object2 = MethodsUtils.findObject(templateProcessor.getContext(), fieldValue);
+        
+        if (fld == object2) {
+            return true;
+        }
+        return false;
+    }
+    
+}
+
+class TestHasRole extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final String[] requiredRoles = attributeName.split("\\|");
+        final AuthenticationSession session = IsisContext.getSession().getAuthenticationSession();
+        final List<String> sessionRoles = session.getRoles();
+        for (final String sessionRole : sessionRoles) {
+            for (final String requiredRole : requiredRoles) {
+                if (requiredRole.trim().equals(sessionRole)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
+
+class TestSet extends Test {
+    @Override
+    boolean test(final TemplateProcessor templateProcessor, final String attributeName, final String targetId) {
+        final boolean valuePresent = templateProcessor.isPropertySet("set");
+        return valuePresent;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Forward.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Forward.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Forward.java
new file mode 100644
index 0000000..9f46a5c
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Forward.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.scimpi.dispatcher.view.control;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class Forward extends AbstractElementProcessor {
+
+    @Override
+    public String getName() {
+        return "forward";
+    }
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String view = templateProcessor.getRequiredProperty(VIEW);
+        templateProcessor.getContext().forward(view);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Redirect.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Redirect.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Redirect.java
new file mode 100644
index 0000000..1554c08
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Redirect.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.scimpi.dispatcher.view.control;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class Redirect extends AbstractElementProcessor {
+
+    @Override
+    public String getName() {
+        return "redirect";
+    }
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String view = templateProcessor.getRequiredProperty(VIEW);
+        templateProcessor.getContext().redirectTo(view);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Unless.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Unless.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Unless.java
new file mode 100644
index 0000000..b2f8451
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/Unless.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.control;
+
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+
+public class Unless extends AbstractConditionalBlock {
+
+    @Override
+    protected void processTags(final boolean isSet, final TemplateProcessor templateProcessor) {
+        if (isSet) {
+            templateProcessor.skipUntilClose();
+            templateProcessor.appendDebug("    skipping segment");
+        } else {
+            templateProcessor.processUtilCloseTag();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "unless";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/When.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/When.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/When.java
new file mode 100644
index 0000000..67f420a
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/control/When.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.control;
+
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+
+public class When extends AbstractConditionalBlock {
+
+    @Override
+    protected void processTags(final boolean isSet, final TemplateProcessor templateProcessor) {
+        if (isSet) {
+            templateProcessor.processUtilCloseTag();
+        } else {
+            templateProcessor.appendDebug("    skipping segment");
+            templateProcessor.skipUntilClose();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "when";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Debug.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Debug.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Debug.java
index d6754ef..6121860 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Debug.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Debug.java
@@ -44,7 +44,8 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 import org.apache.isis.core.metamodel.util.Dump;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class Debug extends AbstractElementProcessor {
@@ -56,19 +57,19 @@ public class Debug extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
-        if (tagProcessor.getContext().isDebugDisabled()) {
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        if (templateProcessor.getContext().isDebugDisabled()) {
             return;
         }
         
-        final String type = tagProcessor.getOptionalProperty(TYPE);
+        final String type = templateProcessor.getOptionalProperty(TYPE);
 
-        final boolean alwaysShow = tagProcessor.isRequested("force", false);
+        final boolean alwaysShow = templateProcessor.isRequested("force", false);
         if (type != null) {
             if (type.equals("system")) {
-                displaySystem(tagProcessor);
+                displaySystem(templateProcessor);
             } else if (type.equals("session")) {
-                displaySession(tagProcessor);
+                displaySession(templateProcessor);
             } else if (type.equals("test")) {
                 final DebugBuilder debug = new DebugHtmlString();
                 debug.appendTitle("Title");
@@ -106,153 +107,153 @@ public class Debug extends AbstractElementProcessor {
                 debug.appendln("A lot of text etc.");
                 debug.endSection();
 
-                tagProcessor.appendHtml(debug.toString());
+                templateProcessor.appendHtml(debug.toString());
                 //request.appendHtml("<pre>" + debug.toString() + "</pre>");
                 
                 debug.close();
                 
             } else if (type.equals("variables")) {
-                displayVariables(tagProcessor);
+                displayVariables(templateProcessor);
             } else if (type.equals("dispatcher")) {
-                displayDispatcher(tagProcessor);
+                displayDispatcher(templateProcessor);
             } else if (type.equals("context")) {
-                displayContext(tagProcessor);
+                displayContext(templateProcessor);
             } else if (type.equals("specifications")) {
-                listSpecifications(tagProcessor);
+                listSpecifications(templateProcessor);
             } else if (type.equals("specification-for")) {
-                specificationFor(tagProcessor);
+                specificationFor(templateProcessor);
             } else if (type.equals("specification")) {
-                specification(tagProcessor);
+                specification(templateProcessor);
             } else if (type.equals("specification-graph")) {
-                specificationGraph(tagProcessor);
+                specificationGraph(templateProcessor);
             } else if (type.equals("object-graph")) {
-                objectGraph(tagProcessor);
+                objectGraph(templateProcessor);
 
             } else if (type.equals("object")) {
-                final String value = tagProcessor.getOptionalProperty(VALUE);
-                final Request context = tagProcessor.getContext();
+                final String value = templateProcessor.getOptionalProperty(VALUE);
+                final Request context = templateProcessor.getContext();
                 final ObjectAdapter object = context.getMappedObject(value);
                 final DebugString str = new DebugString();
                 Dump.adapter(object, str);
                 Dump.graph(object, IsisContext.getAuthenticationSession(), str);
-                tagProcessor.appendHtml("<h2>" + object.getSpecification().getFullIdentifier() + "</h2>");
-                tagProcessor.appendHtml("<pre class=\"debug\">" + str + "</pre>");
+                templateProcessor.appendHtml("<h2>" + object.getSpecification().getFullIdentifier() + "</h2>");
+                templateProcessor.appendHtml("<pre class=\"debug\">" + str + "</pre>");
             }
 
         }
 
-        if (alwaysShow || tagProcessor.getContext().getDebug() == Request.Debug.ON) {
+        if (alwaysShow || templateProcessor.getContext().getDebug() == Request.Debug.ON) {
 
-            final Request context = tagProcessor.getContext();
+            final Request context = templateProcessor.getContext();
 
-            final String id = tagProcessor.getOptionalProperty("object");
+            final String id = templateProcessor.getOptionalProperty("object");
             if (id != null) {
                 final ObjectAdapter object = context.getMappedObject(id);
                 if (object instanceof DebuggableWithTitle) {
                     final DebugString debug = new DebugString();
                     ((DebuggableWithTitle) object).debugData(debug);
-                    tagProcessor.appendHtml("<pre class=\"debug\">" + debug + "</pre>");
+                    templateProcessor.appendHtml("<pre class=\"debug\">" + debug + "</pre>");
                 } else {
-                    tagProcessor.appendHtml(object.toString());
+                    templateProcessor.appendHtml(object.toString());
                 }
             }
 
-            final String variable = tagProcessor.getOptionalProperty("variable");
+            final String variable = templateProcessor.getOptionalProperty("variable");
             if (variable != null) {
                 final Object object = context.getVariable(variable);
-                tagProcessor.appendHtml(variable + " => " + (object == null ? "null" : object.toString()));
+                templateProcessor.appendHtml(variable + " => " + (object == null ? "null" : object.toString()));
             }
 
-            final String list = tagProcessor.getOptionalProperty("list");
+            final String list = templateProcessor.getOptionalProperty("list");
             if (list != null) {
                 final DebugString debug = new DebugString();
                 context.append(debug, list);
-                tagProcessor.appendHtml(debug.toString());
+                templateProcessor.appendHtml(debug.toString());
             }
 
-            final String uri = tagProcessor.getOptionalProperty("uri");
+            final String uri = templateProcessor.getOptionalProperty("uri");
             if (uri != null) {
-                tagProcessor.appendHtml("<pre class=\"debug\">");
-                tagProcessor.appendHtml(context.getUri());
-                tagProcessor.appendHtml("</pre>");
+                templateProcessor.appendHtml("<pre class=\"debug\">");
+                templateProcessor.appendHtml(context.getUri());
+                templateProcessor.appendHtml("</pre>");
             }
 
         }
     }
 
-    protected void objectGraph(final TagProcessor tagProcessor) {
-        final String id = tagProcessor.getOptionalProperty(VALUE);
-        final ObjectAdapter object = tagProcessor.getContext().getMappedObjectOrResult(id);
-        tagProcessor.appendHtml("<h1>Object Graph - " + object + "</h1>");
-        tagProcessor.appendHtml("<pre>");
+    protected void objectGraph(final TemplateProcessor templateProcessor) {
+        final String id = templateProcessor.getOptionalProperty(VALUE);
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(id);
+        templateProcessor.appendHtml("<h1>Object Graph - " + object + "</h1>");
+        templateProcessor.appendHtml("<pre>");
         final DebugBuilder debug = new DebugString();
         Dump.graph(object, null, debug);
-        tagProcessor.appendHtml(debug.toString());
-        tagProcessor.appendHtml("</pre>");
+        templateProcessor.appendHtml(debug.toString());
+        templateProcessor.appendHtml("</pre>");
     }
 
-    protected void specificationFor(final TagProcessor tagProcessor) {
-        final String id = tagProcessor.getOptionalProperty(VALUE);
-        final ObjectAdapter object = tagProcessor.getContext().getMappedObjectOrResult(id);
-        specification(tagProcessor, object.getSpecification());
+    protected void specificationFor(final TemplateProcessor templateProcessor) {
+        final String id = templateProcessor.getOptionalProperty(VALUE);
+        final ObjectAdapter object = templateProcessor.getContext().getMappedObjectOrResult(id);
+        specification(templateProcessor, object.getSpecification());
     }
 
-    protected void specification(final TagProcessor tagProcessor) {
-        final String name = tagProcessor.getOptionalProperty(VALUE);
+    protected void specification(final TemplateProcessor templateProcessor) {
+        final String name = templateProcessor.getOptionalProperty(VALUE);
         final ObjectSpecification spec = getSpecificationLoader().loadSpecification(name);
-        specification(tagProcessor, spec);
+        specification(templateProcessor, spec);
     }
 
-    private void specification(final TagProcessor tagProcessor, final ObjectSpecification spec) {
-        tagProcessor.appendHtml("<h1>Specification - " + spec.getFullIdentifier() + "</h1>");
-        tagProcessor.appendHtml("<p><a href=\"./debug.shtml?type=specification-graph&value=" + spec.getFullIdentifier() + "\">Specification Graph</a></p>");
+    private void specification(final TemplateProcessor templateProcessor, final ObjectSpecification spec) {
+        templateProcessor.appendHtml("<h1>Specification - " + spec.getFullIdentifier() + "</h1>");
+        templateProcessor.appendHtml("<p><a href=\"./debug.shtml?type=specification-graph&value=" + spec.getFullIdentifier() + "\">Specification Graph</a></p>");
         final DebugBuilder debug = new DebugHtmlString();
         specification(spec, debug);
-        tagProcessor.appendHtml(debug.toString());
+        templateProcessor.appendHtml(debug.toString());
     }
 
-    protected void specificationGraph(final TagProcessor tagProcessor) {
-        final String name = tagProcessor.getOptionalProperty(VALUE);
+    protected void specificationGraph(final TemplateProcessor templateProcessor) {
+        final String name = templateProcessor.getOptionalProperty(VALUE);
         final ObjectSpecification spec = getSpecificationLoader().loadSpecification(name);
-        tagProcessor.appendHtml("<h1>Specification Graph - " + spec.getFullIdentifier() + "</h1>");
-        tagProcessor.appendHtml("<p><a href=\"./debug.shtml?type=specification&value=" + spec.getFullIdentifier() + "\">Full Specification</a></p>");
-        tagProcessor.appendHtml("<pre>");
+        templateProcessor.appendHtml("<h1>Specification Graph - " + spec.getFullIdentifier() + "</h1>");
+        templateProcessor.appendHtml("<p><a href=\"./debug.shtml?type=specification&value=" + spec.getFullIdentifier() + "\">Full Specification</a></p>");
+        templateProcessor.appendHtml("<pre>");
         final DebugBuilder debug = new DebugString();
         debug.appendln(spec.getFullIdentifier());
         debug.indent();
         specificationGraph(spec, debug, new ArrayList<ObjectSpecification>());
         debug.unindent();
-        tagProcessor.appendHtml(debug.toString());
-        tagProcessor.appendHtml("</pre>");
+        templateProcessor.appendHtml(debug.toString());
+        templateProcessor.appendHtml("</pre>");
     }
 
-    private void displayContext(final TagProcessor tagProcessor) {
-        tagProcessor.appendHtml("<h1>Context</h1>");
+    private void displayContext(final TemplateProcessor templateProcessor) {
+        templateProcessor.appendHtml("<h1>Context</h1>");
         final DebugHtmlString debugString = new DebugHtmlString();
-        tagProcessor.getContext().append(debugString);
+        templateProcessor.getContext().append(debugString);
         debugString.close();
-        tagProcessor.appendHtml(debugString.toString());
+        templateProcessor.appendHtml(debugString.toString());
     }
 
-    private void displayDispatcher(final TagProcessor tagProcessor) {
-        tagProcessor.appendHtml("<h1>Dispatcher</h1>");
+    private void displayDispatcher(final TemplateProcessor templateProcessor) {
+        templateProcessor.appendHtml("<h1>Dispatcher</h1>");
         final DebugHtmlString debugString = new DebugHtmlString();
         dispatcher.debugData(debugString);
         debugString.close();
-        tagProcessor.appendHtml(debugString.toString());
+        templateProcessor.appendHtml(debugString.toString());
     }
 
-    protected void displayVariables(final TagProcessor tagProcessor) {
-        tagProcessor.appendHtml("<h1>Variables</h1>");
+    protected void displayVariables(final TemplateProcessor templateProcessor) {
+        templateProcessor.appendHtml("<h1>Variables</h1>");
         final DebugHtmlString debug = new DebugHtmlString();
-        final Request context = tagProcessor.getContext();
+        final Request context = templateProcessor.getContext();
         context.append(debug, "variables");
         debug.close();
-        tagProcessor.appendHtml(debug.toString());
+        templateProcessor.appendHtml(debug.toString());
     }
 
-    protected void displaySystem(final TagProcessor tagProcessor) {
-        tagProcessor.appendHtml("<h1>System</h1>");
+    protected void displaySystem(final TemplateProcessor templateProcessor) {
+        templateProcessor.appendHtml("<h1>System</h1>");
         final DebuggableWithTitle[] debugItems = IsisContext.debugSystem();
         for (final DebuggableWithTitle debug : debugItems) {
             final DebugHtmlString debugBuffer = new DebugHtmlString();
@@ -260,12 +261,12 @@ public class Debug extends AbstractElementProcessor {
             debug.debugData(debugBuffer);
             debugBuffer.endSection();
             debugBuffer.close();
-            tagProcessor.appendHtml(debugBuffer.toString());
+            templateProcessor.appendHtml(debugBuffer.toString());
         }
     }
 
-    protected void displaySession(final TagProcessor tagProcessor) {
-        tagProcessor.appendHtml("<h1>Session</h1>");
+    protected void displaySession(final TemplateProcessor templateProcessor) {
+        templateProcessor.appendHtml("<h1>Session</h1>");
         final DebuggableWithTitle[] debugItems = IsisContext.debugSession();
         for (final DebuggableWithTitle debug : debugItems) {
             final DebugHtmlString debugBuffer = new DebugHtmlString();
@@ -273,12 +274,12 @@ public class Debug extends AbstractElementProcessor {
             debug.debugData(debugBuffer);
             debugBuffer.endSection();
             debugBuffer.close();
-            tagProcessor.appendHtml(debugBuffer.toString());
+            templateProcessor.appendHtml(debugBuffer.toString());
         }
     }
 
-    protected void listSpecifications(final TagProcessor tagProcessor) {
-        tagProcessor.appendHtml("<h1>Specifications</h1>");
+    protected void listSpecifications(final TemplateProcessor templateProcessor) {
+        templateProcessor.appendHtml("<h1>Specifications</h1>");
         final List<ObjectSpecification> fullIdentifierList = new ArrayList<ObjectSpecification>(getSpecificationLoader().allSpecifications());
         Collections.sort(fullIdentifierList, ObjectSpecification.COMPARATOR_SHORT_IDENTIFIER_IGNORE_CASE);
         final DebugHtmlString debug = new DebugHtmlString();
@@ -287,7 +288,7 @@ public class Debug extends AbstractElementProcessor {
             debug.appendln(name, specificationLink(spec));
         }
         debug.close();
-        tagProcessor.appendHtml(debug.toString());
+        templateProcessor.appendHtml(debug.toString());
     }
 
     private String specificationLink(final ObjectSpecification specification) {

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugAccessCheck.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugAccessCheck.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugAccessCheck.java
index f48fcad..a418d87 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugAccessCheck.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugAccessCheck.java
@@ -20,14 +20,15 @@
 package org.apache.isis.viewer.scimpi.dispatcher.view.debug;
 
 import org.apache.isis.viewer.scimpi.ForbiddenException;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class DebugAccessCheck extends AbstractElementProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
-        if (tagProcessor.getContext().isDebugDisabled()) {
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        if (templateProcessor.getContext().isDebugDisabled()) {
             throw new ForbiddenException("Debug is disabled");
         }
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugCollectionView.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugCollectionView.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugCollectionView.java
index bab6e54..a39a254 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugCollectionView.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugCollectionView.java
@@ -23,33 +23,34 @@ import java.util.List;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractObjectProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.view.field.LinkedObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.LinkedObject;
 import org.apache.isis.viewer.scimpi.dispatcher.view.other.HelpLink;
 
 public class DebugCollectionView extends AbstractObjectProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor, final ObjectAdapter object) {
-        final String cls = tagProcessor.getOptionalProperty(CLASS, "form");
+    public void process(final TemplateProcessor templateProcessor, final ObjectAdapter object) {
+        final String cls = templateProcessor.getOptionalProperty(CLASS, "form");
         final String classString = " class=\"" + cls + "\"";
-        String title = tagProcessor.getOptionalProperty(FORM_TITLE);
-        final String oddRowClass = tagProcessor.getOptionalProperty(ODD_ROW_CLASS);
-        final String evenRowClass = tagProcessor.getOptionalProperty(EVEN_ROW_CLASS);
-        final boolean showIcons = tagProcessor.isRequested(SHOW_ICON, true);
+        String title = templateProcessor.getOptionalProperty(FORM_TITLE);
+        final String oddRowClass = templateProcessor.getOptionalProperty(ODD_ROW_CLASS);
+        final String evenRowClass = templateProcessor.getOptionalProperty(EVEN_ROW_CLASS);
+        final boolean showIcons = templateProcessor.isRequested(SHOW_ICON, true);
 
+        write(templateProcessor, object, null, null, classString, title, oddRowClass, evenRowClass, showIcons);
     }
 
-    private void write(final TagProcessor tagProcessor, final ObjectAdapter object, final List<ObjectAssociation> fields,
+    private void write(final TemplateProcessor templateProcessor, final ObjectAdapter object, final List<ObjectAssociation> fields,
         final LinkedObject[] linkFields, final String classString, final String title, final String oddRowClass,
         final String evenRowClass, final boolean showIcons) {
-        tagProcessor.appendHtml("<div" + classString + ">");
+        templateProcessor.appendHtml("<div" + classString + ">");
         if (title != null) {
-            tagProcessor.appendHtml("<div class=\"title\">");
-            tagProcessor.appendAsHtmlEncoded(title);
-            tagProcessor.appendHtml("</div>");
-            HelpLink.append(tagProcessor, object.getSpecification().getDescription(), object.getSpecification().getHelp());
+            templateProcessor.appendHtml("<div class=\"title\">");
+            templateProcessor.appendAsHtmlEncoded(title);
+            templateProcessor.appendHtml("</div>");
+            HelpLink.append(templateProcessor, object.getSpecification().getDescription(), object.getSpecification().getHelp());
         }
      /*   
         final List<ObjectAssociation> fields =
@@ -97,7 +98,7 @@ public class DebugCollectionView extends AbstractObjectProcessor {
             request.appendHtml("</div>");
         }
         */
-        tagProcessor.appendHtml("</div>");
+        templateProcessor.appendHtml("</div>");
         
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugObjectView.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugObjectView.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugObjectView.java
index cb16c94..9273adf 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugObjectView.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugObjectView.java
@@ -30,34 +30,34 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractObjectProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.view.display.FieldValue;
-import org.apache.isis.viewer.scimpi.dispatcher.view.field.LinkedObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.determine.LinkedObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.object.FieldValue;
 
 
 public class DebugObjectView extends AbstractObjectProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor, final ObjectAdapter object) {
-        final String classString = " class=\"" + tagProcessor.getOptionalProperty(CLASS, "form debug") + "\"";
-        final String objectLink = tagProcessor.getOptionalProperty(OBJECT + "-" + LINK_VIEW, tagProcessor.getViewPath());
+    public void process(final TemplateProcessor templateProcessor, final ObjectAdapter object) {
+        final String classString = " class=\"" + templateProcessor.getOptionalProperty(CLASS, "form debug") + "\"";
+        final String objectLink = templateProcessor.getOptionalProperty(OBJECT + "-" + LINK_VIEW, templateProcessor.getViewPath());
         // final String collectionLink = request.getOptionalProperty(COLLECTION + "-" + LINK_VIEW, request.getViewPath());
-        final String oddRowClass = tagProcessor.getOptionalProperty(ODD_ROW_CLASS);
-        final String evenRowClass = tagProcessor.getOptionalProperty(EVEN_ROW_CLASS);
-        final boolean showIcons = tagProcessor.isRequested(SHOW_ICON, true);
+        final String oddRowClass = templateProcessor.getOptionalProperty(ODD_ROW_CLASS);
+        final String evenRowClass = templateProcessor.getOptionalProperty(EVEN_ROW_CLASS);
+        final boolean showIcons = templateProcessor.isRequested(SHOW_ICON, true);
 
         ObjectSpecification specification = object.getSpecification();
 
-        tagProcessor.appendHtml("<div" + classString + ">");
-        tagProcessor.appendHtml("<div class=\"title\">");
-        tagProcessor.appendAsHtmlEncoded(specification.getSingularName() + " - " + specification.getFullIdentifier());
-        tagProcessor.appendHtml("</div>");
+        templateProcessor.appendHtml("<div" + classString + ">");
+        templateProcessor.appendHtml("<div class=\"title\">");
+        templateProcessor.appendAsHtmlEncoded(specification.getSingularName() + " - " + specification.getFullIdentifier());
+        templateProcessor.appendHtml("</div>");
 
         Version version = object.getVersion();
-        tagProcessor.appendHtml("<div class=\"version\">");
-        tagProcessor.appendAsHtmlEncoded("#" + version.sequence() + " - " + version.getUser() + " (" + version.getTime() + ")" );
-        tagProcessor.appendHtml("</div>");
+        templateProcessor.appendHtml("<div class=\"version\">");
+        templateProcessor.appendAsHtmlEncoded("#" + version.sequence() + " - " + version.getUser() + " (" + version.getTime() + ")" );
+        templateProcessor.appendHtml("</div>");
 
         final List<ObjectAssociation> fields = specification.getAssociations(ObjectAssociationFilters.ALL);
 
@@ -73,9 +73,9 @@ public class DebugObjectView extends AbstractObjectProcessor {
             } else {
                 cls = " class=\"field " + (evenRowClass == null ? EVEN_ROW_CLASS : evenRowClass) + "\"";
             }
-            tagProcessor.appendHtml("<div " + cls + "><span class=\"label\">");
-            tagProcessor.appendAsHtmlEncoded(field.getName());
-            tagProcessor.appendHtml(":</span>");
+            templateProcessor.appendHtml("<div " + cls + "><span class=\"label\">");
+            templateProcessor.appendAsHtmlEncoded(field.getName());
+            templateProcessor.appendHtml(":</span>");
             
             final boolean isNotParseable =
                 !fields.get(i).getSpecification().containsFacet(ParseableFacet.class);
@@ -84,44 +84,44 @@ public class DebugObjectView extends AbstractObjectProcessor {
      //           linkedObject = new LinkedObject(field.isOneToManyAssociation() ? collectionLink : objectLink);
                 linkedObject = new LinkedObject(objectLink);
             }
-            addField(tagProcessor, object, field, linkedObject, showIcons);
+            addField(templateProcessor, object, field, linkedObject, showIcons);
             
             if (field.isOneToManyAssociation()) {
                 Collection collection = (Collection) field.get(object).getObject();
                 if (collection.size() == 0) {
-                    tagProcessor.appendHtml("[empty]");
+                    templateProcessor.appendHtml("[empty]");
                 } else {
                     // request.appendHtml(collection.size() + " elements");
                    
-                    tagProcessor.appendHtml("<ol>");
+                    templateProcessor.appendHtml("<ol>");
                     
                    for (Object element : collection) {
                        ObjectAdapter adapterFor = IsisContext.getPersistenceSession().getAdapterManager().getAdapterFor(element);
                        IsisContext.getPersistenceSession().resolveImmediately(adapterFor);
 
-                       String id = tagProcessor.getContext().mapObject(adapterFor, linkedObject.getScope(), Scope.INTERACTION);
+                       String id = templateProcessor.getContext().mapObject(adapterFor, linkedObject.getScope(), Scope.INTERACTION);
 
-                       tagProcessor.appendHtml("<li class=\"element\">");
-                       tagProcessor.appendHtml("<a href=\"" + linkedObject.getForwardView() + "?" + linkedObject.getVariable() + "="
-                               + id + tagProcessor.getContext().encodedInteractionParameters() + "\">");
-                       tagProcessor.appendHtml(element.toString());
-                       tagProcessor.appendHtml("</a></li>");
+                       templateProcessor.appendHtml("<li class=\"element\">");
+                       templateProcessor.appendHtml("<a href=\"" + linkedObject.getForwardView() + "?" + linkedObject.getVariable() + "="
+                               + id + templateProcessor.getContext().encodedInteractionParameters() + "\">");
+                       templateProcessor.appendHtml(element.toString());
+                       templateProcessor.appendHtml("</a></li>");
                    }
-                   tagProcessor.appendHtml("</ol>");
+                   templateProcessor.appendHtml("</ol>");
                 }
             } else {
-                FieldValue.write(tagProcessor, object, field, linkedObject, "value", showIcons, 0);
+                FieldValue.write(templateProcessor, object, field, linkedObject, "value", showIcons, 0);
             }
 
             
             
-            tagProcessor.appendHtml("</div>");
+            templateProcessor.appendHtml("</div>");
         }
-        tagProcessor.appendHtml("</div>");
+        templateProcessor.appendHtml("</div>");
     }
 
     protected void addField(
-            final TagProcessor tagProcessor,
+            final TemplateProcessor templateProcessor,
             final ObjectAdapter object,
             final ObjectAssociation field,
             final LinkedObject linkedObject,

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugUsersView.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugUsersView.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugUsersView.java
new file mode 100644
index 0000000..6aad2ca
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebugUsersView.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.view.debug;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class DebugUsersView extends AbstractElementProcessor {
+
+    @Override
+    public String getName() {
+        return "debug-users";
+    }
+
+    @Override
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        final String view = templateProcessor.getContext().getContextPath() + templateProcessor.getContext().getResourceParentPath() + templateProcessor.getContext().getResourceFile();
+
+        templateProcessor.appendHtml("<form class=\"generic action\" action=\"debug-user.app\" method=\"post\" accept-charset=\"ISO-8859-1\">\n");
+        templateProcessor.appendHtml("<div class=\"title\">Add Debug User</div>\n");
+        templateProcessor.appendHtml("<div class=\"field\"><label>User Name:</label><input type=\"text\" name=\"name\" size=\"30\" /></div>\n");
+        templateProcessor.appendHtml("<input type=\"hidden\" name=\"method\" value=\"add\" />\n");
+        templateProcessor.appendHtml("<input type=\"hidden\" name=\"view\" value=\"" + view + "\" />\n");
+        templateProcessor.appendHtml("<input class=\"button\" type=\"submit\" value=\"Add User\" />\n");
+        templateProcessor.appendHtml("</form>\n");
+
+        templateProcessor.appendHtml("<table class=\"debug\">\n<tr><th class=\"title\">Name</th><th class=\"title\"></th></tr>\n");
+        for (final String name : templateProcessor.getContext().getDebugUsers()) {
+            templateProcessor.appendHtml("<tr><th>" + name + "</th><th><a href=\"debug-user.app?method=remove&name=" + name + "&view=" + view + " \">remove</a></th></tr>\n");
+        }
+        templateProcessor.appendHtml("</table>\n");
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebuggerLink.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebuggerLink.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebuggerLink.java
index 64c7ecb..78e7f33 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebuggerLink.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/DebuggerLink.java
@@ -19,30 +19,32 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.debug;
 
+import org.apache.isis.viewer.scimpi.Names;
 import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class DebuggerLink extends AbstractElementProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
-        if (tagProcessor.getContext().isDebugDisabled()) {
-            tagProcessor.skipUntilClose();
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        if (templateProcessor.getContext().isDebugDisabled()) {
+            templateProcessor.skipUntilClose();
             return;
         }
 
-        final Request context = tagProcessor.getContext();
-        final Object result = context.getVariable(Request.RESULT);
-        tagProcessor.appendHtml("<div class=\"debug\">");
-        tagProcessor.appendHtml("<a class=\"debug-link\" href=\"/debug/debug.shtml\" target=\"debug\" title=\"debug\" >...</a>");
+        final Request context = templateProcessor.getContext();
+        final Object result = context.getVariable(Names.RESULT);
+        templateProcessor.appendHtml("<div class=\"debug\">");
+        templateProcessor.appendHtml("<a class=\"debug-link\" href=\"/debug/debug.shtml\" target=\"debug\" title=\"debug\" >...</a>");
         if (result != null) {
-            tagProcessor.appendHtml(" <a href=\"/debug/object.shtml?_result=" + result + "\" target=\"debug\"  title=\"debug instance\">...</a>");
+            templateProcessor.appendHtml(" <a href=\"/debug/object.shtml?_result=" + result + "\" target=\"debug\"  title=\"debug instance\">...</a>");
         }
-        tagProcessor.appendHtml(" <span class=\"debug-link\" onclick=\"$('#page-debug').toggle()\" alt=\"show/hide debug details\">...</span>");
-        tagProcessor.appendHtml("</div>");
+        templateProcessor.appendHtml(" <span class=\"debug-link\" onclick=\"$('#page-debug').toggle()\" alt=\"show/hide debug details\">...</span>");
+        templateProcessor.appendHtml("</div>");
 
-        tagProcessor.processUtilCloseTag();
+        templateProcessor.processUtilCloseTag();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Diagnostics.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Diagnostics.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Diagnostics.java
index 0033c55..9c05671 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Diagnostics.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Diagnostics.java
@@ -24,53 +24,54 @@ import org.apache.isis.core.commons.debug.DebugHtmlString;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.scimpi.Names;
 import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class Diagnostics extends AbstractElementProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
-        if (tagProcessor.getContext().isDebugDisabled()) {
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        if (templateProcessor.getContext().isDebugDisabled()) {
             return;
         }
 
-        final String type = tagProcessor.getOptionalProperty(TYPE, "page");
-        final boolean isForced = tagProcessor.isRequested("force");
-        if (isForced || tagProcessor.getContext().showDebugData()) {
-            tagProcessor.appendHtml("<div class=\"debug\">");
+        final String type = templateProcessor.getOptionalProperty(TYPE, "page");
+        final boolean isForced = templateProcessor.isRequested("force");
+        if (isForced || templateProcessor.getContext().showDebugData()) {
+            templateProcessor.appendHtml("<div class=\"debug\">");
             if ("page".equals(type)) {
-                tagProcessor.appendHtml("<pre>");
-                final Request context = tagProcessor.getContext();
-                tagProcessor.appendHtml("URI:  " + context.getUri());
-                tagProcessor.appendHtml("\n");
-                tagProcessor.appendHtml("File: " + context.fullFilePath(context.getResourceFile()));
-                final String result = (String) tagProcessor.getContext().getVariable(Names.RESULT);
+                templateProcessor.appendHtml("<pre>");
+                final Request context = templateProcessor.getContext();
+                templateProcessor.appendHtml("URI:  " + context.getUri());
+                templateProcessor.appendHtml("\n");
+                templateProcessor.appendHtml("File: " + context.fullFilePath(context.getResourceFile()));
+                final String result = (String) templateProcessor.getContext().getVariable(Names.RESULT);
                 if (result != null) {
-                    tagProcessor.appendHtml("\n");
-                    tagProcessor.appendHtml("Object: " + result);
+                    templateProcessor.appendHtml("\n");
+                    templateProcessor.appendHtml("Object: " + result);
                 }
-                tagProcessor.appendHtml("</pre>");
+                templateProcessor.appendHtml("</pre>");
             } else if ("session".equals(type)) {
-                tagProcessor.appendHtml("<pre>");
+                templateProcessor.appendHtml("<pre>");
                 final AuthenticationSession session = IsisContext.getAuthenticationSession();
-                tagProcessor.appendHtml("Session:  " + session.getUserName() + " " + session.getRoles());
-                tagProcessor.appendHtml("</pre>");
+                templateProcessor.appendHtml("Session:  " + session.getUserName() + " " + session.getRoles());
+                templateProcessor.appendHtml("</pre>");
             } else if ("variables".equals(type)) {
-                final Request context = tagProcessor.getContext();
+                final Request context = templateProcessor.getContext();
                 final DebugHtmlString debug = new DebugHtmlString();
                 debug.appendln("", "");
                 context.append(debug, "variables");
                 debug.close();
-                tagProcessor.appendHtml(debug.toString());
+                templateProcessor.appendHtml(debug.toString());
             } else if ("processing".equals(type)) {
-                tagProcessor.appendHtml("<pre>");
-                tagProcessor.appendHtml(tagProcessor.getContext().getDebugTrace());
-                tagProcessor.appendHtml("</pre>");
+                templateProcessor.appendHtml("<pre>");
+                templateProcessor.appendHtml(templateProcessor.getContext().getDebugTrace());
+                templateProcessor.appendHtml("</pre>");
             } else {
-                tagProcessor.appendHtml("<i>No such type " + type + "</i>");
+                templateProcessor.appendHtml("<i>No such type " + type + "</i>");
             }
-            tagProcessor.appendHtml("</div>");
+            templateProcessor.appendHtml("</div>");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Log.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Log.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Log.java
index ae07894..a63bd21 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Log.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/Log.java
@@ -19,20 +19,21 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.debug;
 
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 import org.apache.log4j.Logger;
 
 public class Log extends AbstractElementProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
-        String name = tagProcessor.getRequiredProperty(NAME);
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
+        String name = templateProcessor.getRequiredProperty(NAME);
         Logger logger = Logger.getLogger(name);
         
-        tagProcessor.pushNewBuffer();
-        tagProcessor.processUtilCloseTag();
-        final String message = tagProcessor.popBuffer();
+        templateProcessor.pushNewBuffer();
+        templateProcessor.processUtilCloseTag();
+        final String message = templateProcessor.popBuffer();
         logger.info(message);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/7700b437/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/LogLevel.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/LogLevel.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/LogLevel.java
index 9c954e6..d567e8a 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/LogLevel.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/debug/LogLevel.java
@@ -22,31 +22,32 @@ package org.apache.isis.viewer.scimpi.dispatcher.view.debug;
 import org.apache.log4j.Level;
 import org.apache.log4j.LogManager;
 
-import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestState;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TemplateProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class LogLevel extends AbstractElementProcessor {
 
     @Override
-    public void process(final TagProcessor tagProcessor) {
+    public void process(final TemplateProcessor templateProcessor, RequestState state) {
 
-        String view = tagProcessor.getOptionalProperty(VIEW, tagProcessor.getViewPath());
-        view = tagProcessor.getContext().fullFilePath(view);
+        String view = templateProcessor.getOptionalProperty(VIEW, templateProcessor.getViewPath());
+        view = templateProcessor.getContext().fullFilePath(view);
         final Level level = LogManager.getRootLogger().getLevel();
-        final boolean showSelector = tagProcessor.isRequested(SHOW_SELECT, true);
+        final boolean showSelector = templateProcessor.isRequested(SHOW_SELECT, true);
         if (showSelector) {
-            tagProcessor.appendHtml("<form action=\"log.app\" type=\"post\" >");
-            tagProcessor.appendHtml("<input type=\"hidden\" name=\"view\" value=\"" + view + "\" />");
-            tagProcessor.appendHtml("<select name=\"level\">");
+            templateProcessor.appendHtml("<form action=\"log.app\" type=\"post\" >");
+            templateProcessor.appendHtml("<input type=\"hidden\" name=\"view\" value=\"" + view + "\" />");
+            templateProcessor.appendHtml("<select name=\"level\">");
             for (final Level l : new Level[] { Level.OFF, Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG, Level.TRACE }) {
                 final String settings = level + "\"" + (level == l ? " selected=\"selected\" " : "");
-                tagProcessor.appendHtml("<option " + settings + ">" + l + "</option>");
+                templateProcessor.appendHtml("<option " + settings + ">" + l + "</option>");
             }
-            tagProcessor.appendHtml("<input type=\"submit\" value=\"Change Level\" />");
-            tagProcessor.appendHtml("</select>");
-            tagProcessor.appendHtml("</form>");
+            templateProcessor.appendHtml("<input type=\"submit\" value=\"Change Level\" />");
+            templateProcessor.appendHtml("</select>");
+            templateProcessor.appendHtml("</form>");
         } else {
-            tagProcessor.appendHtml(level.toString());
+            templateProcessor.appendHtml(level.toString());
         }
     }