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:00 UTC

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

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/edit/Selector.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/edit/Selector.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/edit/Selector.java
deleted file mode 100644
index e814f28..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/edit/Selector.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.viewer.scimpi.dispatcher.view.edit;
-
-import java.util.Iterator;
-
-import org.apache.isis.core.commons.exceptions.UnknownTypeException;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.util.MethodsUtils;
-import org.apache.isis.viewer.scimpi.dispatcher.view.action.ActionForm;
-import org.apache.isis.viewer.scimpi.dispatcher.view.action.CreateFormParameter;
-
-public class Selector extends AbstractElementProcessor {
-
-    @Override
-    public void process(final Request request) {
-        final FormFieldBlock block = (FormFieldBlock) request.getBlockContent();
-        final String field = request.getRequiredProperty(FIELD);
-        if (block.isVisible(field)) {
-            processElement(request, block, field);
-        }
-        request.skipUntilClose();
-    }
-
-    private void processElement(final Request request, final FormFieldBlock block, final String field) {
-        final String type = request.getOptionalProperty(TYPE, "dropdown");
-        if (!request.isPropertySpecified(METHOD) && request.isPropertySpecified(COLLECTION)) {
-            final String id = request.getRequiredProperty(COLLECTION, Request.NO_VARIABLE_CHECKING);
-            final String selector = showSelectionList(request, id, block.getCurrent(field), block.isNullable(field), type);
-            block.replaceContent(field, selector);
-        } else {
-            final String objectId = request.getOptionalProperty(OBJECT);
-            final String methodName = request.getRequiredProperty(METHOD);
-            final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), objectId);
-            final ObjectAction action = MethodsUtils.findAction(object, methodName);
-            if (action.getParameterCount() == 0) {
-                final ObjectAdapter collection = action.execute(object, new ObjectAdapter[0]);
-                final String selector = showSelectionList(request, collection, block.getCurrent(field), block.isNullable(field), type);
-                block.replaceContent(field, selector);
-            } else {
-                final String id = "selector_options";
-                final String id2 = (String) request.getContext().getVariable(id);
-                final String selector = showSelectionList(request, id2, block.getCurrent(field), block.isNullable(field), type);
-
-                final CreateFormParameter parameters = new CreateFormParameter();
-                parameters.objectId = objectId;
-                parameters.methodName = methodName;
-                parameters.buttonTitle = request.getOptionalProperty(BUTTON_TITLE, "Search");
-                parameters.formTitle = request.getOptionalProperty(FORM_TITLE);
-                parameters.className = request.getOptionalProperty(CLASS, "selector");
-                parameters.id = request.getOptionalProperty(ID);
-
-                parameters.resultName = id;
-                parameters.forwardResultTo = request.getContext().getResourceFile();
-                parameters.forwardVoidTo = "error";
-                parameters.forwardErrorTo = parameters.forwardResultTo;
-                parameters.scope = Scope.REQUEST.name();
-                request.pushNewBuffer();
-                ActionForm.createForm(request, parameters);
-                block.replaceContent(field, selector);
-
-                request.appendHtml(request.popBuffer());
-            }
-        }
-    }
-
-    private String showSelectionList(final Request request, final String collectionId, final ObjectAdapter selectedItem, final boolean allowNotSet, final String type) {
-        if (collectionId != null && !collectionId.equals("")) {
-            final ObjectAdapter collection = request.getContext().getMappedObjectOrResult(collectionId);
-            return showSelectionList(request, collection, selectedItem, allowNotSet, type);
-        } else {
-            return null;
-        }
-    }
-
-    private String showSelectionList(final Request request, final ObjectAdapter collection, final ObjectAdapter selectedItem, final boolean allowNotSet, final String type) {
-        final String field = request.getRequiredProperty(FIELD);
-        final CollectionFacet facet = collection.getSpecification().getFacet(CollectionFacet.class);
-
-        if (type.equals("radio")) {
-            return radioButtonList(request, field, allowNotSet, collection, selectedItem, facet);
-        } else if (type.equals("list")) {
-            final String size = request.getOptionalProperty("size", "5");
-            return dropdownList(request, field, allowNotSet, collection, selectedItem, size, facet);
-        } else if (type.equals("dropdown")) {
-            return dropdownList(request, field, allowNotSet, collection, selectedItem, null, facet);
-        } else {
-            throw new UnknownTypeException(type);
-        }
-    }
-
-    private String radioButtonList(final Request request, final String field, final boolean allowNotSet, final ObjectAdapter collection, final ObjectAdapter selectedItem, final CollectionFacet facet) {
-        final RequestContext context = request.getContext();
-        final Iterator<ObjectAdapter> iterator = facet.iterator(collection);
-        final StringBuffer buffer = new StringBuffer();
-        if (allowNotSet) {
-            buffer.append("<input type=\"radio\" name=\"" + field + "\" value=\"null\"></input><br/>\n");
-        }
-        while (iterator.hasNext()) {
-            final ObjectAdapter element = iterator.next();
-            final String elementId = context.mapObject(element, Scope.INTERACTION);
-            final String title = element.titleString();
-            final String checked = element == selectedItem ? "checked=\"checked\"" : "";
-            buffer.append("<input type=\"radio\" name=\"" + field + "\" value=\"" + elementId + "\"" + checked + ">" + title + "</input><br/>\n");
-        }
-
-        return buffer.toString();
-    }
-
-    private String dropdownList(final Request request, final String field, final boolean allowNotSet, final ObjectAdapter collection, final ObjectAdapter selectedItem, String size, final CollectionFacet facet) {
-        final RequestContext context = request.getContext();
-        final Iterator<ObjectAdapter> iterator = facet.iterator(collection);
-        final StringBuffer buffer = new StringBuffer();
-        size = size == null ? "" : " size =\"" + size + "\"";
-        buffer.append("<select name=\"" + field + "\"" + size + " >\n");
-        if (allowNotSet) {
-            buffer.append("  <option value=\"null\"></option>\n");
-        }
-        while (iterator.hasNext()) {
-            final ObjectAdapter element = iterator.next();
-            final String elementId = context.mapObject(element, Scope.INTERACTION);
-            final String title = element.titleString();
-            final String checked = element == selectedItem ? "selected=\"selected\"" : "";
-            buffer.append("  <option value=\"" + elementId + "\"" + checked + ">" + title + "</option>\n");
-        }
-        buffer.append("</select>\n");
-        return buffer.toString();
-    }
-
-    @Override
-    public String getName() {
-        return "selector";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/ExcludeField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/ExcludeField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/ExcludeField.java
index 0c12990..247aa92 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/ExcludeField.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/ExcludeField.java
@@ -19,15 +19,15 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.field;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class ExcludeField extends AbstractElementProcessor {
 
     @Override
-    public void process(final Request request) {
-        final String field = request.getOptionalProperty(NAME);
-        final InclusionList block = (InclusionList) request.getBlockContent();
+    public void process(final TagProcessor tagProcessor) {
+        final String field = tagProcessor.getOptionalProperty(NAME);
+        final InclusionList block = (InclusionList) tagProcessor.getBlockContent();
         block.exclude(field);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/IncludeField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/IncludeField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/IncludeField.java
index bff9858..0d176d2 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/IncludeField.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/IncludeField.java
@@ -19,15 +19,15 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.field;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class IncludeField extends AbstractElementProcessor {
 
     @Override
-    public void process(final Request request) {
-        final String field = request.getOptionalProperty(NAME);
-        final InclusionList block = (InclusionList) request.getBlockContent();
+    public void process(final TagProcessor tagProcessor) {
+        final String field = tagProcessor.getOptionalProperty(NAME);
+        final InclusionList block = (InclusionList) tagProcessor.getBlockContent();
         block.include(field);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/InclusionList.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/InclusionList.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/InclusionList.java
index 1fdc2f6..3a72451 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/InclusionList.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/InclusionList.java
@@ -27,7 +27,7 @@ import com.google.common.collect.Lists;
 
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.viewer.scimpi.dispatcher.BlockContent;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.BlockContent;
 import org.apache.isis.viewer.scimpi.dispatcher.view.form.InputField;
 
 public class InclusionList implements BlockContent {

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkField.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkField.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkField.java
index 74a24e6..e36612d 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkField.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkField.java
@@ -19,21 +19,20 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.field;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.Names;
+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.view.AbstractElementProcessor;
 
 public class LinkField extends AbstractElementProcessor {
 
     @Override
-    public void process(final Request request) {
-        final String field = request.getOptionalProperty(NAME);
-        final String variable = request.getOptionalProperty(REFERENCE_NAME, RequestContext.RESULT);
-        final String scope = request.getOptionalProperty(SCOPE, Scope.INTERACTION.toString());
-        final String forwardView = request.getOptionalProperty(VIEW, "_generic." + Dispatcher.EXTENSION);
-        final LinkedFieldsBlock tag = (LinkedFieldsBlock) request.getBlockContent();
+    public void process(final TagProcessor tagProcessor) {
+        final String field = tagProcessor.getOptionalProperty(NAME);
+        final String variable = tagProcessor.getOptionalProperty(REFERENCE_NAME, Names.RESULT);
+        final String scope = tagProcessor.getOptionalProperty(SCOPE, Scope.INTERACTION.toString());
+        final String forwardView = tagProcessor.getOptionalProperty(VIEW, "_generic." + Names.EXTENSION);
+        final LinkedFieldsBlock tag = (LinkedFieldsBlock) tagProcessor.getBlockContent();
         tag.link(field, variable, scope, forwardView);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
index d2c8548..934e1c1 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/field/LinkedObject.java
@@ -19,8 +19,8 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.field;
 
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
+import org.apache.isis.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request.Scope;
 
 public class LinkedObject {
     private final String variable;
@@ -36,7 +36,7 @@ public class LinkedObject {
     public LinkedObject(final String forwardView) {
         this.forwardView = forwardView;
         scope = Scope.INTERACTION.toString();
-        variable = RequestContext.RESULT;
+        variable = Names.RESULT;
     }
 
     public String getVariable() {

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
index fd44cc8..6d362a6 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/form/HtmlFormBuilder.java
@@ -20,13 +20,13 @@
 package org.apache.isis.viewer.scimpi.dispatcher.view.form;
 
 import org.apache.isis.core.commons.exceptions.UnknownTypeException;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.view.HelpLink;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.other.HelpLink;
 
 public class HtmlFormBuilder {
 
     public static void createForm(
-            final Request request,
+            final TagProcessor tagProcessor,
             final String action,
             final HiddenInputField[] hiddenFields,
             final InputField[] fields,
@@ -41,12 +41,12 @@ public class HtmlFormBuilder {
             final String cancelTo) {
 
         String classSegment = " class=\"" + className + (id == null ? "\"" : "\" id=\"" + id + "\"");
-        request.appendHtml("<form " + classSegment + " action=\"" + action + "\" method=\"post\" accept-charset=\"UTF-8\">\n");
+        tagProcessor.appendHtml("<form " + classSegment + " action=\"" + action + "\" method=\"post\" accept-charset=\"UTF-8\">\n");
         if (formTitle != null && formTitle.trim().length() > 0) {
             classSegment = " class=\"title\"";
-            request.appendHtml("<div" + classSegment + ">");
-            request.appendAsHtmlEncoded(formTitle);
-            request.appendHtml("</div>\n");
+            tagProcessor.appendHtml("<div" + classSegment + ">");
+            tagProcessor.appendAsHtmlEncoded(formTitle);
+            tagProcessor.appendHtml("</div>\n");
         }
 
         // TODO reinstate fieldsets when we can specify them
@@ -54,51 +54,51 @@ public class HtmlFormBuilder {
 
         final String cls = "errors";
         if (errors != null) {
-            request.appendHtml("<div class=\"" + cls + "\">");
-            request.appendAsHtmlEncoded(errors);
-            request.appendHtml("</div>");
+            tagProcessor.appendHtml("<div class=\"" + cls + "\">");
+            tagProcessor.appendAsHtmlEncoded(errors);
+            tagProcessor.appendHtml("</div>");
         }
         for (final HiddenInputField hiddenField : hiddenFields) {
             if (hiddenField == null) {
                 continue;
             }
-            request.appendHtml("  <input type=\"hidden\" name=\"" + hiddenField.getName() + "\" value=\"");
-            request.appendAsHtmlEncoded(hiddenField.getValue());
-            request.appendHtml("\" />\n");
+            tagProcessor.appendHtml("  <input type=\"hidden\" name=\"" + hiddenField.getName() + "\" value=\"");
+            tagProcessor.appendAsHtmlEncoded(hiddenField.getValue());
+            tagProcessor.appendHtml("\" />\n");
         }
-        request.appendHtml(request.getContext().interactionFields());
+        tagProcessor.appendHtml(tagProcessor.getContext().interactionFields());
         for (final InputField fld : fields) {
             if (fld.isHidden()) {
-                request.appendHtml("  <input type=\"hidden\" name=\"" + fld.getName() + "\" value=\"");
-                request.appendAsHtmlEncoded(fld.getValue());
-                request.appendHtml("\" />\n");
+                tagProcessor.appendHtml("  <input type=\"hidden\" name=\"" + fld.getName() + "\" value=\"");
+                tagProcessor.appendAsHtmlEncoded(fld.getValue());
+                tagProcessor.appendHtml("\" />\n");
             } else {
                 final String errorSegment = fld.getErrorText() == null ? "" : "<span class=\"error\">" + fld.getErrorText() + "</span>";
                 final String fieldSegment = createField(fld);
                 final String helpSegment = HelpLink.createHelpSegment(fld.getDescription(), fld.getHelpReference());
                 final String title = fld.getDescription().equals("") ? "" : " title=\"" + fld.getDescription() + "\"";
-                request.appendHtml("  <div class=\"field " + fld.getName() + "\"><label class=\"label\" " + title + ">");
-                request.appendAsHtmlEncoded(fld.getLabel());
-                request.appendHtml(labelDelimiter + "</label>" + fieldSegment + errorSegment + helpSegment + "</div>\n");
+                tagProcessor.appendHtml("  <div class=\"field " + fld.getName() + "\"><label class=\"label\" " + title + ">");
+                tagProcessor.appendAsHtmlEncoded(fld.getLabel());
+                tagProcessor.appendHtml(labelDelimiter + "</label>" + fieldSegment + errorSegment + helpSegment + "</div>\n");
             }
         }
 
-        request.appendHtml("  <input class=\"button\" type=\"submit\" value=\"");
-        request.appendAsHtmlEncoded(buttonTitle);
-        request.appendHtml("\" name=\"execute\" />\n");
-        HelpLink.append(request, description, helpReference);
+        tagProcessor.appendHtml("  <input class=\"button\" type=\"submit\" value=\"");
+        tagProcessor.appendAsHtmlEncoded(buttonTitle);
+        tagProcessor.appendHtml("\" name=\"execute\" />\n");
+        HelpLink.append(tagProcessor, description, helpReference);
         // TODO alllow forms to be cancelled, returning to previous page.
         // request.appendHtml("  <div class=\"action\"><a class=\"button\" href=\"reset\">Cancel</a></div>");
 
         if (cancelTo != null) {
-            request.appendHtml("  <input class=\"button\" type=\"button\" value=\"");
-            request.appendAsHtmlEncoded("Cancel");
-            request.appendHtml("\" onclick=\"window.location = '" + cancelTo + "'\" name=\"cancel\" />\n");
+            tagProcessor.appendHtml("  <input class=\"button\" type=\"button\" value=\"");
+            tagProcessor.appendAsHtmlEncoded("Cancel");
+            tagProcessor.appendHtml("\" onclick=\"window.location = '" + cancelTo + "'\" name=\"cancel\" />\n");
         }
 
         // TODO reinstate fieldsets when we can specify them
         // request.appendHtml("</fieldset>\n");
-        request.appendHtml("</form>\n");
+        tagProcessor.appendHtml("</form>\n");
     }
 
     private static String createField(final InputField field) {
@@ -143,7 +143,7 @@ public class HtmlFormBuilder {
         final String disabled = field.isEditable() ? "" : " disabled=\"disabled\"";
         final String maxLength = field.getMaxLength() == 0 ? "" : " maxlength=\"" + field.getMaxLength() + "\"";
         return "<textarea" + requiredSegment + " name=\"" + field.getName() + "\"" + columnsSegment + rowsSegment + wrapSegment
-                + maxLength + disabled + ">" + Request.getEncoder().encoder(field.getValue()) + "</textarea>";
+                + maxLength + disabled + ">" + TagProcessor.getEncoder().encoder(field.getValue()) + "</textarea>";
     }
 
     private static String createPasswordField(final InputField field) {
@@ -157,7 +157,7 @@ public class HtmlFormBuilder {
 
     private static String createTextField(final InputField field, final String type, final String additionalAttributes) {
         final String value = field.getValue();
-        final String valueSegment = value == null ? "" : " value=\"" + Request.getEncoder().encoder(value) + "\"";
+        final String valueSegment = value == null ? "" : " value=\"" + TagProcessor.getEncoder().encoder(value) + "\"";
         final String lengthSegment = field.getWidth() == 0 ? "" : " size=\"" + field.getWidth() + "\"";
         final String maxLengthSegment = field.getMaxLength() == 0 ? "" : " maxlength=\"" + field.getMaxLength() + "\"";
         final String requiredSegment = !field.isRequired() ? "" : " required";
@@ -187,7 +187,7 @@ public class HtmlFormBuilder {
             if (field.getType() == InputField.TEXT && options[i].equals("__other")) {
                 offerOther = true;
             } else {
-                str.append("    <option value=\"" + Request.getEncoder().encoder(ids[i]) + "\"" + selectedSegment + ">" + Request.getEncoder().encoder(options[i]) + "</option>\n");
+                str.append("    <option value=\"" + TagProcessor.getEncoder().encoder(ids[i]) + "\"" + selectedSegment + ">" + TagProcessor.getEncoder().encoder(options[i]) + "</option>\n");
             }
         }
         if (!field.isRequired() || length == 0) {

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logoff.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logoff.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logoff.java
index 1632f5d..0fa8e84 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logoff.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logoff.java
@@ -19,15 +19,15 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.logon;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.logon.LogoutAction;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.action.LogoutAction;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class Logoff extends AbstractElementProcessor {
 
     @Override
-    public void process(final Request request) {
-        LogoutAction.logoutUser(request.getContext());
+    public void process(final TagProcessor tagProcessor) {
+        LogoutAction.logoutUser(tagProcessor.getContext());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logon.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logon.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logon.java
index b25ccbe..63a47ee 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logon.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Logon.java
@@ -24,12 +24,12 @@ import java.util.List;
 
 import org.apache.isis.core.commons.authentication.AnonymousSession;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-import org.apache.isis.viewer.scimpi.dispatcher.edit.FieldEditState;
-import org.apache.isis.viewer.scimpi.dispatcher.edit.FormState;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+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.structure.FieldEditState;
+import org.apache.isis.viewer.scimpi.dispatcher.structure.FormState;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.view.form.HiddenInputField;
 import org.apache.isis.viewer.scimpi.dispatcher.view.form.HtmlFormBuilder;
 import org.apache.isis.viewer.scimpi.dispatcher.view.form.InputField;
@@ -37,32 +37,32 @@ import org.apache.isis.viewer.scimpi.dispatcher.view.form.InputField;
 public class Logon extends AbstractElementProcessor {
 
     @Override
-    public void process(final Request request) {
-        String view = request.getOptionalProperty(VIEW);
-        RequestContext context = request.getContext();
+    public void process(final TagProcessor tagProcessor) {
+        String view = tagProcessor.getOptionalProperty(VIEW);
+        Request context = tagProcessor.getContext();
         if (view == null) {
             view = (String) context.getVariable("login-path");
         }
 
         final boolean isNotLoggedIn = IsisContext.getSession().getAuthenticationSession() instanceof AnonymousSession;
         if (isNotLoggedIn) {            
-            loginForm(request, view);
+            loginForm(tagProcessor, view);
         }
     }
 
-    public static void loginForm(final Request request, final String view) {
-        final String object = request.getOptionalProperty(OBJECT);
-        final String method = request.getOptionalProperty(METHOD, "logon");
-        final String result = request.getOptionalProperty(RESULT_NAME, "_user");
-        final String resultScope = request.getOptionalProperty(SCOPE, Scope.SESSION.name());
-        final String isisUser = request.getOptionalProperty("isis-user", "_web_default");
-        final String formId = request.getOptionalProperty(FORM_ID, request.nextFormId());
-        final String labelDelimiter = request.getOptionalProperty(LABEL_DELIMITER, ":");
+    public static void loginForm(final TagProcessor tagProcessor, final String view) {
+        final String object = tagProcessor.getOptionalProperty(OBJECT);
+        final String method = tagProcessor.getOptionalProperty(METHOD, "logon");
+        final String result = tagProcessor.getOptionalProperty(RESULT_NAME, "_user");
+        final String resultScope = tagProcessor.getOptionalProperty(SCOPE, Scope.SESSION.name());
+        final String isisUser = tagProcessor.getOptionalProperty("isis-user", "_web_default");
+        final String formId = tagProcessor.getOptionalProperty(FORM_ID, tagProcessor.nextFormId());
+        final String labelDelimiter = tagProcessor.getOptionalProperty(LABEL_DELIMITER, ":");
 
         // TODO error if all values are not set (not if use type is not set and all others are still defaults);
 
         if (object != null) {
-            RequestContext context = request.getContext();
+            Request context = tagProcessor.getContext();
             context.addVariable(LOGON_OBJECT, object, Scope.SESSION);
             context.addVariable(LOGON_METHOD, method, Scope.SESSION);
             context.addVariable(LOGON_RESULT_NAME, result, Scope.SESSION);
@@ -71,7 +71,7 @@ public class Logon extends AbstractElementProcessor {
             context.addVariable(LOGON_FORM_ID, formId, Scope.SESSION);
         }
         
-        final String error = request.getOptionalProperty(ERROR, request.getContext().getRequestedFile());
+        final String error = tagProcessor.getOptionalProperty(ERROR, tagProcessor.getContext().getRequestedFile());
         final List<HiddenInputField> hiddenFields = new ArrayList<HiddenInputField>();
         hiddenFields.add(new HiddenInputField(ERROR, error));
         if (view != null) {
@@ -79,12 +79,12 @@ public class Logon extends AbstractElementProcessor {
         }
         hiddenFields.add(new HiddenInputField("_" + FORM_ID, formId));
 
-        final FormState entryState = (FormState) request.getContext().getVariable(ENTRY_FIELDS);
+        final FormState entryState = (FormState) tagProcessor.getContext().getVariable(ENTRY_FIELDS);
         boolean isforThisForm = entryState != null && entryState.isForForm(formId);
         if (entryState != null && entryState.isForForm(formId)) {
         }
         final InputField nameField = createdField("username", "User Name", InputField.TEXT, isforThisForm ? entryState : null);
-        final String width = request.getOptionalProperty("width");
+        final String width = tagProcessor.getOptionalProperty("width");
         if (width != null) {
             final int w = Integer.valueOf(width).intValue();
             nameField.setWidth(w);
@@ -92,12 +92,12 @@ public class Logon extends AbstractElementProcessor {
         final InputField passwordField = createdField("password", "Password", InputField.PASSWORD, isforThisForm ? entryState : null);
         final InputField[] fields = new InputField[] { nameField, passwordField, };
 
-        final String formTitle = request.getOptionalProperty(FORM_TITLE);
-        final String loginButtonTitle = request.getOptionalProperty(BUTTON_TITLE, "Log in");
-        final String className = request.getOptionalProperty(CLASS, "login");
-        final String id = request.getOptionalProperty(ID, "logon");
+        final String formTitle = tagProcessor.getOptionalProperty(FORM_TITLE);
+        final String loginButtonTitle = tagProcessor.getOptionalProperty(BUTTON_TITLE, "Log in");
+        final String className = tagProcessor.getOptionalProperty(CLASS, "login");
+        final String id = tagProcessor.getOptionalProperty(ID, "logon");
 
-        HtmlFormBuilder.createForm(request, "logon.app", hiddenFields.toArray(new HiddenInputField[hiddenFields.size()]), fields,
+        HtmlFormBuilder.createForm(tagProcessor, "logon.app", hiddenFields.toArray(new HiddenInputField[hiddenFields.size()]), fields,
                 className, id, formTitle, labelDelimiter, null, null, loginButtonTitle,
                 isforThisForm && entryState != null ? entryState.getError() : null , null);        
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/RestrictAccess.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/RestrictAccess.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/RestrictAccess.java
index 83f2597..baf7eef 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/RestrictAccess.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/RestrictAccess.java
@@ -18,22 +18,22 @@
  */
 package org.apache.isis.viewer.scimpi.dispatcher.view.logon;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class RestrictAccess extends AbstractElementProcessor {
     private static final String LOGIN_VIEW = "login-view";
-    private static final String DEFAULT_LOGIN_VIEW = "login." + Dispatcher.EXTENSION;
+    private static final String DEFAULT_LOGIN_VIEW = "login." + Names.EXTENSION;
 
     public String getName() {
         return "restrict-access";
     }
 
-    public void process(Request request) {
-        if (!request.getContext().isUserAuthenticated()) { 
-            final String view = request.getOptionalProperty(LOGIN_VIEW, DEFAULT_LOGIN_VIEW);
-            request.getContext().redirectTo(view);
+    public void process(TagProcessor tagProcessor) {
+        if (!tagProcessor.getContext().isUserAuthenticated()) { 
+            final String view = tagProcessor.getOptionalProperty(LOGIN_VIEW, DEFAULT_LOGIN_VIEW);
+            tagProcessor.getContext().redirectTo(view);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Secure.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Secure.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Secure.java
index 17cd472..85c9a23 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Secure.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/Secure.java
@@ -21,19 +21,19 @@ package org.apache.isis.viewer.scimpi.dispatcher.view.logon;
 
 import org.apache.isis.core.commons.authentication.AnonymousSession;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class Secure extends AbstractElementProcessor {
     private static final String LOGIN_VIEW = "login-view";
 
     @Override
-    public void process(final Request request) {
+    public void process(final TagProcessor tagProcessor) {
         final boolean isLoggedIn = !(IsisContext.getSession().getAuthenticationSession() instanceof AnonymousSession);
         if (!isLoggedIn) {
             IsisContext.getMessageBroker().addWarning("You are not currently logged in! Please log in so you can continue.");
-            final String view = request.getOptionalProperty(LOGIN_VIEW, "/login.shtml");
-            request.getContext().redirectTo(view);
+            final String view = tagProcessor.getOptionalProperty(LOGIN_VIEW, "/login.shtml");
+            tagProcessor.getContext().redirectTo(view);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/User.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/User.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/User.java
index 4254746..2a0a1e8 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/User.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/logon/User.java
@@ -20,53 +20,53 @@
 package org.apache.isis.viewer.scimpi.dispatcher.view.logon;
 
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class User extends AbstractElementProcessor {
     private static final String LOGIN_VIEW = "login-view";
-    private static final String DEFAULT_LOGIN_VIEW = "login." + Dispatcher.EXTENSION;
+    private static final String DEFAULT_LOGIN_VIEW = "login." + Names.EXTENSION;
     private static final String LOGOUT_VIEW = "logout-view";
-    private static final String DEFAULT_LOGOUT_VIEW = "logout." + Dispatcher.EXTENSION;
+    private static final String DEFAULT_LOGOUT_VIEW = "logout." + Names.EXTENSION;
 
     @Override
-    public void process(final Request request) {
-        final boolean isAuthenticatedn = request.getContext().isUserAuthenticated();
-        request.appendHtml("<div class=\"user\">");
+    public void process(final TagProcessor tagProcessor) {
+        final boolean isAuthenticatedn = tagProcessor.getContext().isUserAuthenticated();
+        tagProcessor.appendHtml("<div class=\"user\">");
         if (isAuthenticatedn) {
-            displayUserAndLogoutLink(request);
+            displayUserAndLogoutLink(tagProcessor);
         } else {
-            displayLoginForm(request);
+            displayLoginForm(tagProcessor);
         }
-        request.appendHtml("</div>");
+        tagProcessor.appendHtml("</div>");
     }
 
-    public void displayLoginForm(final Request request) {
-        String loginView = request.getOptionalProperty(LOGIN_VIEW);
+    public void displayLoginForm(final TagProcessor tagProcessor) {
+        String loginView = tagProcessor.getOptionalProperty(LOGIN_VIEW);
         if (loginView == null) {
-            Logon.loginForm(request, ".");
+            Logon.loginForm(tagProcessor, ".");
         } else {
             if (loginView.trim().length() == 0) {
                 loginView = DEFAULT_LOGIN_VIEW;
             }
-            request.appendHtml("<a div class=\"link\" href=\"" + loginView + "\">Log in</a>");
+            tagProcessor.appendHtml("<a div class=\"link\" href=\"" + loginView + "\">Log in</a>");
         }
     }
 
-    public void displayUserAndLogoutLink(final Request request) {
-        String user = request.getOptionalProperty(NAME);
+    public void displayUserAndLogoutLink(final TagProcessor tagProcessor) {
+        String user = tagProcessor.getOptionalProperty(NAME);
         if (user == null) {
-            user = (String) request.getContext().getVariable("_username");
+            user = (String) tagProcessor.getContext().getVariable("_username");
         }
         if (user == null) {
             user = IsisContext.getAuthenticationSession().getUserName();
         }
-        request.appendHtml("Welcome <span class=\"name\">");
-        request.appendAsHtmlEncoded(user);
-        request.appendHtml("</span>, ");
-        final String logoutView = request.getOptionalProperty(LOGOUT_VIEW, DEFAULT_LOGOUT_VIEW);
-        request.appendHtml("<a class=\"link\" href=\"logout.app?view=" + logoutView + "\">Log out</a>");
+        tagProcessor.appendHtml("Welcome <span class=\"name\">");
+        tagProcessor.appendAsHtmlEncoded(user);
+        tagProcessor.appendHtml("</span>, ");
+        final String logoutView = tagProcessor.getOptionalProperty(LOGOUT_VIEW, DEFAULT_LOGOUT_VIEW);
+        tagProcessor.appendHtml("<a class=\"link\" href=\"logout.app?view=" + logoutView + "\">Log out</a>");
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java
new file mode 100644
index 0000000..9bc5987
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/HelpLink.java
@@ -0,0 +1,72 @@
+/*
+ *  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.other;
+
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class HelpLink extends AbstractElementProcessor {
+
+    private static String site;
+    private static String suffix;
+
+    public static void append(final TagProcessor tagProcessor, final String description, final String helpReference) {
+        tagProcessor.appendHtml(createHelpSegment(description, helpReference));
+    }
+
+    public static String createHelpSegment(final String description, final String helpReference) {
+        if (site == null) {
+            site = IsisContext.getConfiguration().getString(ConfigurationConstants.ROOT + "scimpi.help-site", "/help/");
+        }
+        if (suffix == null) {
+            suffix = IsisContext.getConfiguration().getString(ConfigurationConstants.ROOT + "scimpi.help-suffix", "shtml");
+            if (suffix == null || suffix.equals("")) {
+                suffix = "";
+            } else {
+                suffix = "." + suffix;
+            }
+        }
+
+        if (helpReference == null || helpReference.equals("No help available")) {
+            return "";
+        } else {
+            final String elementClass = "help-link";
+            final String link = site + helpReference + suffix;
+            final String linkText = "Help";
+            final String target = "scimpi-help";
+            final String titleSection = description == null ? "" : ("\" title=\"" + description);
+            return "<a class=\"" + elementClass + "\" href=\"" + link + "\" target=\"" + target + titleSection + "\"><img src=\"/images/help.png\" alt=\"" + linkText + "\" /></a>";
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "help";
+    }
+
+    @Override
+    public void process(final TagProcessor tagProcessor) {
+        final String description = null;
+        final String helpReference = tagProcessor.getRequiredProperty("ref");
+        append(tagProcessor, description, helpReference);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java
new file mode 100644
index 0000000..d328921
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/History.java
@@ -0,0 +1,150 @@
+/*
+ *  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.other;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+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.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
+
+public class History extends AbstractElementProcessor {
+
+    private static final String _HISTORY = "_history";
+
+    static class Crumb {
+        String name;
+        String link;
+    }
+
+    static class Crumbs implements Serializable {
+        private static final long serialVersionUID = 1L;
+        private static final int MAXIMUM_SIZE = 10;
+        private final List<Crumb> crumbs = new ArrayList<Crumb>();
+
+        public void add(final String name, final String link) {
+            for (final Crumb crumb : crumbs) {
+                if (crumb.link.equals(link)) {
+                    crumbs.remove(crumb);
+                    crumbs.add(crumb);
+                    return;
+                }
+            }
+
+            final Crumb crumb = new Crumb();
+            crumb.name = name;
+            crumb.link = link;
+            crumbs.add(crumb);
+
+            if (crumbs.size() > MAXIMUM_SIZE) {
+                crumbs.remove(0);
+            }
+        }
+
+        public void clear() {
+            crumbs.clear();
+        }
+
+        public boolean isEmpty() {
+            return crumbs.size() == 0;
+        }
+
+        public int size() {
+            return crumbs.size();
+        }
+
+        public Iterable<Crumb> iterator() {
+            return crumbs;
+        }
+
+    }
+
+    @Override
+    public String getName() {
+        return "history";
+    }
+
+    @Override
+    public void process(final TagProcessor tagProcessor) {
+        final String action = tagProcessor.getOptionalProperty("action", "display");
+        final Crumbs crumbs = getCrumbs(tagProcessor);
+        if (action.equals("display") && crumbs != null) {
+            write(crumbs, tagProcessor);
+        } else if (action.equals("link")) {
+            final String name = tagProcessor.getRequiredProperty(NAME);
+            final String link = tagProcessor.getRequiredProperty(LINK_VIEW);
+            crumbs.add(name, link);
+        } else if (action.equals("object")) {
+            final String id = tagProcessor.getOptionalProperty(OBJECT);
+            final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), id);
+            final String name = object.titleString();
+            String link = tagProcessor.getRequiredProperty(LINK_VIEW);
+            link += "?_result=" + id;
+            crumbs.add(name, link);
+        } else if (action.equals("return")) {
+
+        } else if (action.equals("clear")) {
+            crumbs.clear();
+        }
+
+    }
+
+    public void write(final Crumbs crumbs, final TagProcessor tagProcessor) {
+        if (crumbs.isEmpty()) {
+            return;
+        }
+
+        tagProcessor.appendHtml("<div id=\"history\">");
+        int i = 0;
+        final int length = crumbs.size();
+        for (final Crumb crumb : crumbs.iterator()) {
+            final String link = crumb.link;
+            if (i > 0) {
+                tagProcessor.appendHtml("<span class=\"separator\"> | </span>");
+            }
+            if (i == length - 1 || link == null) {
+                tagProcessor.appendHtml("<span class=\"disabled\">");
+                tagProcessor.appendHtml(crumb.name);
+                tagProcessor.appendHtml("</span>");
+            } else {
+                tagProcessor.appendHtml("<a class=\"linked\" href=\"" + link + "\">");
+                tagProcessor.appendHtml(crumb.name);
+                tagProcessor.appendHtml("</a>");
+            }
+            i++;
+        }
+        tagProcessor.appendHtml("</div>");
+    }
+
+    private Crumbs getCrumbs(final TagProcessor tagProcessor) {
+        final Request context = tagProcessor.getContext();
+        Crumbs crumbs = (Crumbs) context.getVariable(_HISTORY);
+        if (crumbs == null) {
+            crumbs = new Crumbs();
+            context.addVariable(_HISTORY, crumbs, Scope.SESSION);
+        }
+        return crumbs;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java
new file mode 100644
index 0000000..5ae6dff
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/other/VersionNumber.java
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.scimpi.dispatcher.view.other;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.isis.viewer.scimpi.ScimpiException;
+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.view.AbstractElementProcessor;
+
+public class VersionNumber extends AbstractElementProcessor {
+
+    private static final String MARKER = "Implementation-Build: ";
+    private static final String FILE = "/META-INF/MANIFEST.MF";
+    private String version;
+
+    @Override
+    public String getName() {
+        return "version-number";
+    }
+
+    @Override
+    public void process(final TagProcessor tagProcessor) {
+        if (version == null) {
+            version = "0000"; // default revision number
+            loadRevisonNumber(tagProcessor.getContext());
+        }
+        tagProcessor.appendHtml(version);
+    }
+
+    private void loadRevisonNumber(final Request context) {
+        BufferedReader reader;
+        try {
+            String file = FILE;
+
+            file = context.findFile(FILE);
+            reader = new BufferedReader(new InputStreamReader(context.openStream(file)));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (line.startsWith(MARKER)) {
+                    version = line.substring(MARKER.length());
+                    break;
+                }
+            }
+            reader.close();
+        } catch (final IOException e) {
+            throw new ScimpiException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractConditionalBlock.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractConditionalBlock.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractConditionalBlock.java
index 293429e..1572197 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractConditionalBlock.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractConditionalBlock.java
@@ -35,10 +35,10 @@ 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.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
 import org.apache.isis.viewer.scimpi.dispatcher.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public abstract class AbstractConditionalBlock extends AbstractElementProcessor {
 
@@ -107,24 +107,24 @@ public abstract class AbstractConditionalBlock extends AbstractElementProcessor
     }
 
     @Override
-    public void process(final Request request) {
-        final String id = request.getOptionalProperty(OBJECT);
+    public void process(final TagProcessor tagProcessor) {
+        final String id = tagProcessor.getOptionalProperty(OBJECT);
 
         boolean checkMade = false;
         boolean allConditionsMet = true;
 
-        final String[] propertyNames = request.getAttributes().getPropertyNames(new String[] { "object", "collection" });
+        final String[] propertyNames = tagProcessor.getAttributes().getPropertyNames(new String[] { "object", "collection" });
         for (final String propertyName : propertyNames) {
             boolean result;
             if (propertyName.equals("set")) {
-                result = request.isPropertySet("set");
+                result = tagProcessor.isPropertySet("set");
             } else {
                 final Test test = tests.get(propertyName);
                 if (test == null) {
                     throw new ScimpiException("No such test: " + propertyName);
                 }
-                final String attributeValue = request.getOptionalProperty(propertyName, false);
-                result = test.test(request, attributeValue, id);
+                final String attributeValue = tagProcessor.getOptionalProperty(propertyName, false);
+                result = test.test(tagProcessor, attributeValue, id);
                 if (test.negateResult) {
                     result = !result;
                 }
@@ -263,9 +263,9 @@ public abstract class AbstractConditionalBlock extends AbstractElementProcessor
          * &= hasMatchingRole; }
          */
 
-        final String persistent = request.getOptionalProperty("persistent");
+        final String persistent = tagProcessor.getOptionalProperty("persistent");
         if (persistent != null) {
-            final ObjectAdapter object = request.getContext().getMappedObjectOrResult(persistent);
+            final ObjectAdapter object = tagProcessor.getContext().getMappedObjectOrResult(persistent);
             checkMade = true;
             allConditionsMet &= object.representsPersistent();
         }
@@ -277,11 +277,11 @@ public abstract class AbstractConditionalBlock extends AbstractElementProcessor
          * cls.isAssignableFrom(object.getObject().getClass())); checkMade =
          * true; allConditionsMet &= hasType;; }
          */
-        if (request.isPropertySpecified("empty")) {
-            if (request.isPropertySet("empty")) {
-                final String collection = request.getOptionalProperty("empty");
+        if (tagProcessor.isPropertySpecified("empty")) {
+            if (tagProcessor.isPropertySet("empty")) {
+                final String collection = tagProcessor.getOptionalProperty("empty");
                 if (collection != null) {
-                    final ObjectAdapter object = request.getContext().getMappedObjectOrResult(collection);
+                    final ObjectAdapter object = tagProcessor.getContext().getMappedObjectOrResult(collection);
                     final CollectionFacet facet = object.getSpecification().getFacet(CollectionFacet.class);
                     checkMade = true;
                     allConditionsMet &= facet.size(object) == 0;
@@ -292,20 +292,20 @@ public abstract class AbstractConditionalBlock extends AbstractElementProcessor
             }
         }
 
-        if (request.isPropertySpecified("set")) {
-            final boolean valuePresent = request.isPropertySet("set");
+        if (tagProcessor.isPropertySpecified("set")) {
+            final boolean valuePresent = tagProcessor.isPropertySet("set");
             checkMade = true;
             allConditionsMet &= valuePresent;
         }
 
         if (checkMade) {
-            processTags(allConditionsMet, request);
+            processTags(allConditionsMet, tagProcessor);
         } else {
             throw new ScimpiException("No condition in " + getName());
         }
     }
 
-    protected abstract void processTags(boolean isSet, Request request);
+    protected abstract void processTags(boolean isSet, TagProcessor tagProcessor);
 
 }
 
@@ -313,7 +313,7 @@ abstract class Test {
     String name;
     boolean negateResult;
 
-    abstract boolean test(Request request, String attributeName, String targetId);
+    abstract boolean test(TagProcessor tagProcessor, String attributeName, String targetId);
 
     protected Class<?> forClass(final String className) {
         Class<?> cls = null;
@@ -347,8 +347,8 @@ abstract class Test {
 
 class TestVariableExists extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        Object variable = request.getContext().getVariable(attributeName);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        Object variable = tagProcessor.getContext().getVariable(attributeName);
         if (variable instanceof String && ((String) variable).equals("")) {
             return false;
         }
@@ -358,8 +358,8 @@ class TestVariableExists extends Test {
 
 class TestVariableTrue extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final Object variable = request.getContext().getVariable(attributeName);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final Object variable = tagProcessor.getContext().getVariable(attributeName);
         final Boolean value = variable instanceof Boolean ? (Boolean) variable : Boolean.valueOf((String) variable);
         return value != null && value.booleanValue();
     }
@@ -367,16 +367,16 @@ class TestVariableTrue extends Test {
 
 class TestObjectPersistent extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = request.getContext().getMappedObjectOrResult(attributeName);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = tagProcessor.getContext().getMappedObjectOrResult(attributeName);
         return object.representsPersistent();
     }
 }
 
 class TestObjectType extends TestObjectPersistent {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final Class<?> cls = forClass(attributeName);
         final boolean hasType = object != null && (cls == null || cls.isAssignableFrom(object.getObject().getClass()));
         return hasType;
@@ -385,8 +385,8 @@ class TestObjectType extends TestObjectPersistent {
 
 class TestCollectionType extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.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()));
@@ -396,8 +396,8 @@ class TestCollectionType extends Test {
 
 class TestCollectionFull extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), attributeName);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), attributeName);
         final CollectionFacet facet = object.getSpecification().getFacet(CollectionFacet.class);
         final boolean isEmpty = facet != null && facet.size(object) == 0;
         return !isEmpty;
@@ -406,8 +406,8 @@ class TestCollectionFull extends Test {
 
 class TestMethodExists extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final List<? extends ObjectAction> objectActions = object.getSpecification().getObjectActions(ActionType.USER, Contributed.INCLUDED);
         boolean methodExists = false;
         for (final ObjectAction objectAssociation : objectActions) {
@@ -422,8 +422,8 @@ class TestMethodExists extends Test {
 
 class TestMethodVisible extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.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);
@@ -433,8 +433,8 @@ class TestMethodVisible extends Test {
 
 class TestMethodUseable extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.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);
@@ -444,8 +444,8 @@ class TestMethodUseable extends Test {
 
 class TestFieldExists extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final List<? extends ObjectAssociation> objectFields = object.getSpecification().getAssociations();
         boolean fieldExists = false;
         for (final ObjectAssociation objectAssociation : objectFields) {
@@ -460,8 +460,8 @@ class TestFieldExists extends Test {
 
 class TestFieldVisible extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final ObjectAssociation objectField = findProperty(attributeName, object);
         final Consent visible = objectField.isVisible(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE);
         return visible.isAllowed();
@@ -470,8 +470,8 @@ class TestFieldVisible extends Test {
 
 class TestFieldEditable extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final ObjectAssociation objectField = findProperty(attributeName, object);
         final Consent usable = objectField.isUsable(IsisContext.getAuthenticationSession(), object, Where.ANYWHERE);
         return usable.isAllowed();
@@ -480,8 +480,8 @@ class TestFieldEditable extends Test {
 
 class TestFieldType extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final Class<?> cls = forClass(attributeName);
         final boolean hasType = object != null && (cls == null || cls.isAssignableFrom(object.getObject().getClass()));
         return hasType;
@@ -490,8 +490,8 @@ class TestFieldType extends Test {
 
 class TestFieldSet extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), targetId);
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.getContext(), targetId);
         final ObjectAssociation objectField = findProperty(attributeName, object);
         IsisContext.getPersistenceSession().resolveField(object, objectField);
         final ObjectAdapter fld = objectField.get(object);
@@ -513,20 +513,20 @@ class TestFieldSet extends Test {
 
 class TestFieldValue extends Test {
     @Override
-    boolean test(Request request, String attributeName, String targetId) {
+    boolean test(TagProcessor tagProcessor, 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(request.getContext(), targetId);
+        final ObjectAdapter object = MethodsUtils.findObject(tagProcessor.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(request.getContext(), fieldValue);
+        final ObjectAdapter object2 = MethodsUtils.findObject(tagProcessor.getContext(), fieldValue);
         
         if (fld == object2) {
             return true;
@@ -538,7 +538,7 @@ class TestFieldValue extends Test {
 
 class TestHasRole extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
         final String[] requiredRoles = attributeName.split("\\|");
         final AuthenticationSession session = IsisContext.getSession().getAuthenticationSession();
         final List<String> sessionRoles = session.getRoles();
@@ -555,8 +555,8 @@ class TestHasRole extends Test {
 
 class TestSet extends Test {
     @Override
-    boolean test(final Request request, final String attributeName, final String targetId) {
-        final boolean valuePresent = request.isPropertySet("set");
+    boolean test(final TagProcessor tagProcessor, final String attributeName, final String targetId) {
+        final boolean valuePresent = tagProcessor.isPropertySet("set");
         return valuePresent;
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractLink.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractLink.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractLink.java
index 743be2d..b5777a4 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractLink.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/AbstractLink.java
@@ -23,30 +23,31 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.ForbiddenException;
-import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+import org.apache.isis.viewer.scimpi.ForbiddenException;
+import org.apache.isis.viewer.scimpi.Names;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+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.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public abstract class AbstractLink extends AbstractElementProcessor {
 
     @Override
-    public void process(final Request request) {
-        final String title = request.getOptionalProperty(FORM_TITLE);
-        final String name = request.getOptionalProperty(NAME);
-        final boolean showAsButton = request.isRequested("show-as-button", false);
-        final String linkClass = request.getOptionalProperty(CLASS, showAsButton ? "button" : defaultLinkClass());
-        final String containerClass = request.getOptionalProperty(CONTAINER_CLASS, "action");
-        final String object = request.getOptionalProperty(OBJECT);
-        final RequestContext context = request.getContext();
-        String objectId = object != null ? object : (String) context.getVariable(RequestContext.RESULT);
+    public void process(final TagProcessor tagProcessor) {
+        final String title = tagProcessor.getOptionalProperty(FORM_TITLE);
+        final String name = tagProcessor.getOptionalProperty(NAME);
+        final boolean showAsButton = tagProcessor.isRequested("show-as-button", false);
+        final String linkClass = tagProcessor.getOptionalProperty(CLASS, showAsButton ? "button" : defaultLinkClass());
+        final String containerClass = tagProcessor.getOptionalProperty(CONTAINER_CLASS, "action");
+        final String object = tagProcessor.getOptionalProperty(OBJECT);
+        final Request context = tagProcessor.getContext();
+        String objectId = object != null ? object : (String) context.getVariable(Names.RESULT);
         ObjectAdapter adapter = MethodsUtils.findObject(context, objectId);
 
         // REVIEW this is common used code
-        final String fieldName = request.getOptionalProperty(FIELD);
+        final String fieldName = tagProcessor.getOptionalProperty(FIELD);
         if (fieldName != null) {
             final ObjectAssociation field = adapter.getSpecification().getAssociation(fieldName);
             if (field == null) {
@@ -70,37 +71,37 @@ public abstract class AbstractLink extends AbstractElementProcessor {
             }
         }
 
-        if (adapter != null && valid(request, adapter)) {
-            final String variable = request.getOptionalProperty("param-name", RequestContext.RESULT);
+        if (adapter != null && valid(tagProcessor, adapter)) {
+            final String variable = tagProcessor.getOptionalProperty("param-name", Names.RESULT);
             final String variableSegment = variable + "=" + objectId;
 
-            String view = request.getOptionalProperty(VIEW);
+            String view = tagProcessor.getOptionalProperty(VIEW);
             if (view == null) {
                 view = defaultView();
             }
             view = context.fullUriPath(view);
             final String classSegment = " class=\"" + linkClass + "\"";
             final String titleSegment = title == null ? "" : (" title=\"" + title + "\"");
-            String additionalSegment = additionalParameters(request);
+            String additionalSegment = additionalParameters(tagProcessor);
             additionalSegment = additionalSegment == null ? "" : "&amp;" + additionalSegment;
             if (showAsButton) {
-                request.appendHtml("<div class=\"" + containerClass + "\">");
+                tagProcessor.appendHtml("<div class=\"" + containerClass + "\">");
             }
-            request.appendHtml("<a" + classSegment + titleSegment + " href=\"" + view + "?" + variableSegment + context.encodedInteractionParameters() + additionalSegment + "\">");
-            request.pushNewBuffer();
-            request.processUtilCloseTag();
-            final String buffer = request.popBuffer();
+            tagProcessor.appendHtml("<a" + classSegment + titleSegment + " href=\"" + view + "?" + variableSegment + context.encodedInteractionParameters() + additionalSegment + "\">");
+            tagProcessor.pushNewBuffer();
+            tagProcessor.processUtilCloseTag();
+            final String buffer = tagProcessor.popBuffer();
             if (buffer.trim().length() > 0) {
-                request.appendHtml(buffer);
+                tagProcessor.appendHtml(buffer);
             } else {
-                request.appendAsHtmlEncoded(linkLabel(name, adapter));
+                tagProcessor.appendAsHtmlEncoded(linkLabel(name, adapter));
             }
-            request.appendHtml("</a>");
+            tagProcessor.appendHtml("</a>");
             if (showAsButton) {
-                request.appendHtml("</div>");
+                tagProcessor.appendHtml("</div>");
             }
         } else {
-            request.skipUntilClose();
+            tagProcessor.skipUntilClose();
         }
     }
 
@@ -110,11 +111,11 @@ public abstract class AbstractLink extends AbstractElementProcessor {
 
     protected abstract String linkLabel(String name, ObjectAdapter object);
 
-    protected String additionalParameters(final Request request) {
+    protected String additionalParameters(final TagProcessor tagProcessor) {
         return null;
     }
 
-    protected abstract boolean valid(Request request, ObjectAdapter adapter);
+    protected abstract boolean valid(TagProcessor tagProcessor, ObjectAdapter adapter);
 
     protected abstract String defaultView();
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockDefine.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockDefine.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockDefine.java
index cea5d11..8b7f645 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockDefine.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockDefine.java
@@ -19,10 +19,10 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.simple;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request.RepeatMarker;
+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.TagProcessor.RepeatMarker;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class BlockDefine extends AbstractElementProcessor {
 
@@ -32,11 +32,11 @@ public class BlockDefine extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final Request request) {
-        final String name = request.getOptionalProperty(NAME, "unamed");
-        final RepeatMarker start = request.createMarker();
-        request.skipUntilClose();
-        request.getContext().addVariable("_block-" + name, start, Scope.REQUEST);
+    public void process(final TagProcessor tagProcessor) {
+        final String name = tagProcessor.getOptionalProperty(NAME, "unamed");
+        final RepeatMarker start = tagProcessor.createMarker();
+        tagProcessor.skipUntilClose();
+        tagProcessor.getContext().addVariable("_block-" + name, start, Scope.REQUEST);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockUse.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockUse.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockUse.java
index efd6128..014daf2 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockUse.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/simple/BlockUse.java
@@ -19,9 +19,9 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.view.simple;
 
-import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
-import org.apache.isis.viewer.scimpi.dispatcher.processor.Request.RepeatMarker;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.TagProcessor.RepeatMarker;
+import org.apache.isis.viewer.scimpi.dispatcher.view.AbstractElementProcessor;
 
 public class BlockUse extends AbstractElementProcessor {
 
@@ -31,15 +31,15 @@ public class BlockUse extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final Request request) {
-        final String name = request.getOptionalProperty(NAME, "unamed");
-        request.closeEmpty();
-        final RepeatMarker end = request.createMarker();
+    public void process(final TagProcessor tagProcessor) {
+        final String name = tagProcessor.getOptionalProperty(NAME, "unamed");
+        tagProcessor.closeEmpty();
+        final RepeatMarker end = tagProcessor.createMarker();
 
-        final RepeatMarker marker = (RepeatMarker) request.getContext().getVariable("_block-" + name);
+        final RepeatMarker marker = (RepeatMarker) tagProcessor.getContext().getVariable("_block-" + name);
         marker.repeat();
 
-        request.processUtilCloseTag();
+        tagProcessor.processUtilCloseTag();
         end.repeat();
     }