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

[08/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/debug/DebugAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugAction.java
deleted file mode 100644
index b0f2910..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugAction.java
+++ /dev/null
@@ -1,243 +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.debug;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.core.commons.debug.DebugString;
-import org.apache.isis.core.commons.debug.DebuggableWithTitle;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
-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.metamodel.util.Dump;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
-import org.apache.isis.viewer.scimpi.dispatcher.ForbiddenException;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-
-public class DebugAction implements Action {
-    private final Dispatcher dispatcher;
-
-    public DebugAction(final Dispatcher dispatcher) {
-        this.dispatcher = dispatcher;
-    }
-
-    @Override
-    public String getName() {
-        return "debug";
-    }
-
-    @Override
-    public void debug(final DebugBuilder debug) {
-    }
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-        if (context.isDebugDisabled()) {
-            throw new ForbiddenException("Can't access debug action when debug is disabled");
-        }
-
-        final String action = context.getParameter("action");
-        if ("list-i18n".equals(action)) {
-            i18n(context, null);
-        } else if ("list-authorization".equals(action)) {
-            authorization(context, null);
-        } else if (context.getParameter("mode") != null) {
-            final boolean isDebugOn = context.getParameter("mode").equals("debug");
-            context.addVariable("debug-on", isDebugOn, Scope.SESSION);
-            // TODO need to use configuration to find path
-            context.setRequestPath("/debug/debug.shtml");
-        } else {
-
-            // TODO remove - replaced by Debug tag
-            final DebugHtmlWriter view = new DebugHtmlWriter(context.getWriter(), true);
-            view.appendln("<div class=\"links\">");
-            view.appendln("<a href=\"debug.app?action=system\">System</a>");
-            view.appendln(" | <a href=\"debug.app?action=specifications\">List specifications</a>");
-            view.appendln(" | <a href=\"debug.app?action=list-i18n\">I18N File</a>");
-            view.appendln(" | <a href=\"debug.app?action=list-authorization\">Authorization File</a>");
-            view.appendln(" | <a href=\"debug.app?action=context\">Context</a>");
-            view.appendln(" | <a href=\"debug.app?action=dispatcher\">Dispatcher</a>");
-            view.appendln("</div>");
-
-            if ("specifications".equals(action)) {
-                listSpecifications(view);
-            } else if ("specification".equals(action)) {
-                // specification(context, view);
-            } else if ("object".equals(action)) {
-                object(context, view);
-            } else if ("system".equals(action)) {
-                system(context, view);
-            } else if ("context".equals(action)) {
-                context.append(view);
-            } else if ("dispatcher".equals(action)) {
-                dispatcher.debug(view);
-            }
-
-            context.clearRequestedPath();
-        }
-    }
-
-    private void object(final RequestContext context, final DebugHtmlWriter view) {
-        final ObjectAdapter object = context.getMappedObjectOrResult(context.getParameter("object"));
-        final DebugString str = new DebugString();
-        Dump.adapter(object, str);
-        Dump.graph(object, IsisContext.getAuthenticationSession(), str);
-        view.appendTitle(object.getSpecification().getFullIdentifier());
-        view.appendln("<pre class=\"debug\">" + str + "</pre>");
-    }
-
-    private void system(final RequestContext context, final DebugHtmlWriter view) {
-        final DebuggableWithTitle[] debug = IsisContext.debugSystem();
-        view.appendTitle("System");
-        for (final DebuggableWithTitle element2 : debug) {
-            final DebugString str = new DebugString();
-            element2.debugData(str);
-            view.appendTitle(element2.debugTitle());
-            view.appendln("<pre class=\"debug\">" + str + "</pre>");
-        }
-    }
-
-    private void i18n(final RequestContext context, final DebugHtmlWriter view) {
-        final Collection<ObjectSpecification> allSpecifications = getSpecificationLoader().allSpecifications();
-        final List<ObjectSpecification> specs = Lists.newArrayList(allSpecifications);
-        Collections.sort(specs, new Comparator<ObjectSpecification>() {
-            @Override
-            public int compare(final ObjectSpecification o1, final ObjectSpecification o2) {
-                return o1.getShortIdentifier().compareTo(o2.getShortIdentifier());
-            }
-        });
-        final Function<ObjectSpecification, String> className = ObjectSpecification.FUNCTION_FULLY_QUALIFIED_CLASS_NAME;
-        final List<String> fullIdentifierList = Lists.newArrayList(Collections2.transform(specs, className));
-        for (final String fullIdentifier : fullIdentifierList) {
-            final ObjectSpecification spec = getSpecificationLoader().loadSpecification(fullIdentifier);
-            if (spec.getAssociations().size() == 0 && spec.getObjectActions(Contributed.EXCLUDED).size() == 0) {
-                continue;
-            }
-            final String name = spec.getIdentifier().toClassIdentityString();
-            context.getWriter().append("# " + spec.getShortIdentifier() + "\n");
-            for (final ObjectAssociation assoc : spec.getAssociations()) {
-                context.getWriter().append("#" + name + ".property." + assoc.getId() + ".name" + "=\n");
-                context.getWriter().append("#" + name + ".property." + assoc.getId() + ".description" + "=\n");
-                context.getWriter().append("#" + name + ".property." + assoc.getId() + ".help" + "=\n");
-            }
-            for (final ObjectAction action : spec.getObjectActions(Contributed.EXCLUDED)) {
-                context.getWriter().append("#" + name + ".action." + action.getId() + ".name" + "=\n");
-                context.getWriter().append("#" + name + ".action." + action.getId() + ".description" + "=\n");
-                context.getWriter().append("#" + name + ".action." + action.getId() + ".help" + "=\n");
-            }
-            context.getWriter().append("\n");
-        }
-    }
-
-    private void authorization(final RequestContext context, final DebugHtmlWriter view) {
-        final Collection<ObjectSpecification> allSpecifications = getSpecificationLoader().allSpecifications();
-        final List<ObjectSpecification> specs = Lists.newArrayList(allSpecifications);
-        Collections.sort(specs, new Comparator<ObjectSpecification>() {
-            @Override
-            public int compare(final ObjectSpecification o1, final ObjectSpecification o2) {
-                return o1.getShortIdentifier().compareTo(o2.getShortIdentifier());
-            }
-        });
-        final Function<ObjectSpecification, String> className = ObjectSpecification.FUNCTION_FULLY_QUALIFIED_CLASS_NAME;
-        final List<String> fullIdentifierList = Lists.newArrayList(Collections2.transform(specs, className));
-        for (final String fullIdentifier : fullIdentifierList) {
-            final ObjectSpecification spec = getSpecificationLoader().loadSpecification(fullIdentifier);
-            if (spec.getAssociations().size() == 0 && spec.getObjectActions(Contributed.EXCLUDED).size() == 0) {
-                continue;
-            }
-            final String name = spec.getIdentifier().toClassIdentityString();
-            context.getWriter().append("# " + spec.getShortIdentifier() + "\n");
-            context.getWriter().append("" + name + ":roles\n");
-            for (final ObjectAssociation assoc : spec.getAssociations()) {
-                context.getWriter().append("#" + name + "#" + assoc.getId() + ":roles\n");
-                // context.getWriter().append("#" + name + ".property." +
-                // assoc.getId() + ".description" + "=\n");
-                // context.getWriter().append("#" + name + ".property." +
-                // assoc.getId() + ".help" + "=\n");
-            }
-            for (final ObjectAction action : spec.getObjectActions(Contributed.EXCLUDED)) {
-                context.getWriter().append("#" + name + "#" + action.getId() + "():roles\n");
-                // context.getWriter().append("#" + name + ".action." +
-                // action.getId() + ".description" + "=\n");
-                // context.getWriter().append("#" + name + ".action." +
-                // action.getId() + ".help" + "=\n");
-            }
-            context.getWriter().append("\n");
-        }
-    }
-
-    private void listSpecifications(final DebugHtmlWriter view) {
-        final List<ObjectSpecification> fullIdentifierList = new ArrayList<ObjectSpecification>(getSpecificationLoader().allSpecifications());
-        Collections.sort(fullIdentifierList, ObjectSpecification.COMPARATOR_SHORT_IDENTIFIER_IGNORE_CASE);
-        view.appendTitle("Specifications");
-        for (final ObjectSpecification spec : fullIdentifierList) {
-            final String name = spec.getSingularName();
-            view.appendln(name, "");
-            // view.appendln(name, specificationLink(spec));
-        }
-
-        /*
-         * new Comparator<ObjectSpecification>() { public int
-         * compare(ObjectSpecification o1, ObjectSpecification o2) { return
-         * o1.getSingularName().compareTo(o2.getSingularName()); }});
-         * 
-         * /* Collection<ObjectSpecification> allSpecifications =
-         * getSpecificationLoader().allSpecifications(); Collection<String> list
-         * = Collections2.transform(allSpecifications,
-         * ObjectSpecification.COMPARATOR_SHORT_IDENTIFIER_IGNORE_CASE); final
-         * List<String> fullIdentifierList = Lists.newArrayList(list); /*
-         * Collections.sort(fullIdentifierList, new
-         * Comparator<ObjectSpecification>() { public int
-         * compare(ObjectSpecification o1, ObjectSpecification o2) { return
-         * o1.getSingularName().compareTo(o2.getSingularName()); }});
-         */
-        /*
-         * view.divider("Specifications"); for (String fullIdentifier :
-         * fullIdentifierList) { ObjectSpecification spec =
-         * getSpecificationLoader().loadSpecification(fullIdentifier); String
-         * name = spec.getSingularName(); view.appendRow(name,
-         * specificationLink(spec)); }
-         */
-    }
-
-    protected SpecificationLoaderSpi getSpecificationLoader() {
-        return IsisContext.getSpecificationLoader();
-    }
-
-    @Override
-    public void init() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugHtmlWriter.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugHtmlWriter.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugHtmlWriter.java
deleted file mode 100644
index 112bc77..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugHtmlWriter.java
+++ /dev/null
@@ -1,45 +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.debug;
-
-import java.io.PrintWriter;
-
-import org.apache.isis.core.commons.debug.DebugHtmlStringAbstract;
-
-public class DebugHtmlWriter extends DebugHtmlStringAbstract {
-
-    private final PrintWriter writer;
-
-    public DebugHtmlWriter(final PrintWriter writer, final boolean createPage) {
-        super(createPage);
-        this.writer = writer;
-        header();
-    }
-
-    @Override
-    protected void appendHtml(final String html) {
-        writer.println(html);
-    }
-
-    @Override
-    protected void doClose() {
-        footer();
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUserAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUserAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUserAction.java
deleted file mode 100644
index 461ce84..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUserAction.java
+++ /dev/null
@@ -1,71 +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.debug;
-
-import java.io.IOException;
-
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-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;
-
-public class DebugUserAction implements Action {
-
-    private final DebugUsers debugUsers;
-
-    public DebugUserAction(final DebugUsers debugUsers) {
-        this.debugUsers = debugUsers;
-    }
-
-    @Override
-    public String getName() {
-        return "debug-user";
-    }
-
-    @Override
-    public void debug(final DebugBuilder debug) {
-    }
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-        if (context.isDebugDisabled()) {
-            throw new ForbiddenException("Can't access debug action when debug is disabled");
-        }
-
-        final String method = context.getParameter(METHOD);
-        final String name = context.getParameter(NAME);
-        final String view = context.getParameter(VIEW);
-
-        if (method != null && method.equals("add")) {
-            debugUsers.add(name);
-        } else if (method != null && method.equals("remove")) {
-            debugUsers.remove(name);
-        } else {
-            throw new ScimpiException("Invalid debug-user action");
-        }
-
-        context.setRequestPath(view);
-    }
-
-    @Override
-    public void init() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsers.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsers.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsers.java
deleted file mode 100644
index 81a215a..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsers.java
+++ /dev/null
@@ -1,97 +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.debug;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.config.ConfigurationConstants;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
-
-public class DebugUsers {
-
-    private static Logger LOG = Logger.getLogger(DebugUsers.class);
-
-    private enum DebugMode {
-        OFF, ON, NAMED, SYSADMIN_ONLY
-    }
-
-    private static List<String> debugUsers = new ArrayList<String>();
-    private static DebugMode debugMode;
-
-    public void initialize() {
-        if (debugMode != null) {
-            throw new ScimpiException("Debug mode is already set up!");
-        }
-
-        final String debugUserEntry = IsisContext.getConfiguration().getString(ConfigurationConstants.ROOT + "scimpi.debug.users", "");
-        final String[] users = debugUserEntry.split("\\|");
-        for (final String name : users) {
-            debugUsers.add(name.trim());
-        }
-
-        final String debugModeEntry = IsisContext.getConfiguration().getString(ConfigurationConstants.ROOT + "scimpi.debug.mode");
-        if (debugModeEntry != null) {
-            try {
-                debugMode = DebugMode.valueOf(debugModeEntry.toUpperCase());
-                LOG.info("Debug mode set to " + debugMode);
-            } catch (final IllegalArgumentException e) {
-                LOG.error("Invalid debug mode - " + debugModeEntry + " - mode set to OFF");
-                debugMode = DebugMode.OFF;
-            }
-        } else {
-            debugMode = DebugMode.OFF;
-        }
-    }
-
-    public boolean isDebugEnabled(final AuthenticationSession session) {
-        if (debugMode == DebugMode.ON) {
-            return true;
-        } else if (session != null && debugMode == DebugMode.SYSADMIN_ONLY && session.getRoles().contains("sysadmin")) {
-            return true;
-        } else if (session != null && debugMode == DebugMode.NAMED && (debugUsers.contains(session.getUserName()) || session.getRoles().contains("sysadmin"))) {
-            return true;
-        }
-        return false;
-    }
-
-    public List<String> getNames() {
-        final ArrayList<String> users = new ArrayList<String>(debugUsers);
-        Collections.sort(users);
-        return users;
-    }
-
-    public void add(final String name) {
-        if (!debugUsers.contains(name)) {
-            debugUsers.add(name);
-            LOG.info("Added '" + debugMode + "' to debug users list");
-        }
-    }
-
-    public void remove(final String name) {
-        debugUsers.remove(name);
-        LOG.info("Removed '" + debugMode + "' from debug users list");
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsersView.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsersView.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsersView.java
index 360c48a..3243d92 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsersView.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/DebugUsersView.java
@@ -19,8 +19,8 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.debug;
 
-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 DebugUsersView extends AbstractElementProcessor {
 
@@ -30,21 +30,21 @@ public class DebugUsersView extends AbstractElementProcessor {
     }
 
     @Override
-    public void process(final Request request) {
-        final String view = request.getContext().getContextPath() + request.getContext().getResourceParentPath() + request.getContext().getResourceFile();
+    public void process(final TagProcessor tagProcessor) {
+        final String view = tagProcessor.getContext().getContextPath() + tagProcessor.getContext().getResourceParentPath() + tagProcessor.getContext().getResourceFile();
 
-        request.appendHtml("<form class=\"generic action\" action=\"debug-user.app\" method=\"post\" accept-charset=\"ISO-8859-1\">\n");
-        request.appendHtml("<div class=\"title\">Add Debug User</div>\n");
-        request.appendHtml("<div class=\"field\"><label>User Name:</label><input type=\"text\" name=\"name\" size=\"30\" /></div>\n");
-        request.appendHtml("<input type=\"hidden\" name=\"method\" value=\"add\" />\n");
-        request.appendHtml("<input type=\"hidden\" name=\"view\" value=\"" + view + "\" />\n");
-        request.appendHtml("<input class=\"button\" type=\"submit\" value=\"Add User\" />\n");
-        request.appendHtml("</form>\n");
+        tagProcessor.appendHtml("<form class=\"generic action\" action=\"debug-user.app\" method=\"post\" accept-charset=\"ISO-8859-1\">\n");
+        tagProcessor.appendHtml("<div class=\"title\">Add Debug User</div>\n");
+        tagProcessor.appendHtml("<div class=\"field\"><label>User Name:</label><input type=\"text\" name=\"name\" size=\"30\" /></div>\n");
+        tagProcessor.appendHtml("<input type=\"hidden\" name=\"method\" value=\"add\" />\n");
+        tagProcessor.appendHtml("<input type=\"hidden\" name=\"view\" value=\"" + view + "\" />\n");
+        tagProcessor.appendHtml("<input class=\"button\" type=\"submit\" value=\"Add User\" />\n");
+        tagProcessor.appendHtml("</form>\n");
 
-        request.appendHtml("<table class=\"debug\">\n<tr><th class=\"title\">Name</th><th class=\"title\"></th></tr>\n");
-        for (final String name : request.getContext().getDebugUsers()) {
-            request.appendHtml("<tr><th>" + name + "</th><th><a href=\"debug-user.app?method=remove&name=" + name + "&view=" + view + " \">remove</a></th></tr>\n");
+        tagProcessor.appendHtml("<table class=\"debug\">\n<tr><th class=\"title\">Name</th><th class=\"title\"></th></tr>\n");
+        for (final String name : tagProcessor.getContext().getDebugUsers()) {
+            tagProcessor.appendHtml("<tr><th>" + name + "</th><th><a href=\"debug-user.app?method=remove&name=" + name + "&view=" + view + " \">remove</a></th></tr>\n");
         }
-        request.appendHtml("</table>\n");
+        tagProcessor.appendHtml("</table>\n");
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorDetails.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorDetails.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorDetails.java
index 3049b26..0459390 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorDetails.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorDetails.java
@@ -19,8 +19,8 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.debug;
 
-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 ErrorDetails extends AbstractElementProcessor {
@@ -29,7 +29,7 @@ public class ErrorDetails extends AbstractElementProcessor {
         return "error-details";
     }
 
-    public void process(final Request request) {
-        request.appendHtml(request.getContext().getErrorDetails());
+    public void process(final TagProcessor tagProcessor) {
+        tagProcessor.appendHtml(tagProcessor.getContext().getErrorDetails());
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorMessage.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorMessage.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorMessage.java
index 07538ce..dfc48cf 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorMessage.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorMessage.java
@@ -19,8 +19,8 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.debug;
 
-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 ErrorMessage extends AbstractElementProcessor {
@@ -29,7 +29,7 @@ public class ErrorMessage extends AbstractElementProcessor {
         return "error-message";
     }
 
-    public void process(final Request request) {
-        request.appendAsHtmlEncoded(request.getContext().getErrorMessage());
+    public void process(final TagProcessor tagProcessor) {
+        tagProcessor.appendAsHtmlEncoded(tagProcessor.getContext().getErrorMessage());
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorReference.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorReference.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorReference.java
index 75700cc..49e0b24 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorReference.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/ErrorReference.java
@@ -19,8 +19,8 @@
 
 package org.apache.isis.viewer.scimpi.dispatcher.debug;
 
-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 ErrorReference extends AbstractElementProcessor {
@@ -29,7 +29,7 @@ public class ErrorReference extends AbstractElementProcessor {
         return "error-reference";
     }
 
-    public void process(final Request request) {
-        request.appendAsHtmlEncoded(request.getContext().getErrorReference());
+    public void process(final TagProcessor tagProcessor) {
+        tagProcessor.appendAsHtmlEncoded(tagProcessor.getContext().getErrorReference());
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/LogAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/LogAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/LogAction.java
deleted file mode 100644
index 138213a..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/debug/LogAction.java
+++ /dev/null
@@ -1,76 +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.debug;
-
-import java.io.IOException;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-import org.apache.isis.viewer.scimpi.dispatcher.NotLoggedInException;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-
-public class LogAction implements Action {
-
-    private static final Logger LOG = Logger.getLogger(LogAction.class);
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-
-        final AuthenticationSession session = context.getSession();
-        if (session == null) {
-            throw new NotLoggedInException();
-        }
-
-        final String levelName = (String) context.getVariable("level");
-
-        final Level level = Level.toLevel(levelName);
-        boolean changeLogged = false;
-        if (Level.INFO.isGreaterOrEqual(LogManager.getRootLogger().getLevel())) {
-            LOG.info("log level changed to " + level);
-            changeLogged = true;
-        }
-        LogManager.getRootLogger().setLevel(level);
-        if (!changeLogged) {
-            LOG.info("log level changed to " + level);
-        }
-        final String view = (String) context.getVariable("view");
-        context.setRequestPath(view);
-
-    }
-
-    @Override
-    public String getName() {
-        return "log";
-    }
-
-    @Override
-    public void init() {
-    }
-
-    @Override
-    public void debug(final DebugBuilder debug) {
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/EditAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/EditAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/EditAction.java
deleted file mode 100644
index f78575f..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/EditAction.java
+++ /dev/null
@@ -1,269 +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.edit;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.profiles.Localization;
-import org.apache.isis.core.commons.authentication.AnonymousSession;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.version.Version;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.Veto;
-import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
-import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.core.runtime.system.transaction.MessageBroker;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
-import org.apache.isis.viewer.scimpi.dispatcher.NotLoggedInException;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-
-public class EditAction implements Action {
-    public static final String ACTION = "edit";
-
-    // REVIEW: should provide this rendering context, rather than hardcoding.
-    // the net effect currently is that class members annotated with 
-    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
-    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
-    // for any other value for Where
-    private final Where where = Where.ANYWHERE;
-
-    @Override
-    public String getName() {
-        return ACTION;
-    }
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-        AuthenticationSession session = context.getSession();
-        if (session == null) {
-            session = new AnonymousSession();
-        }
-
-        try {
-            final String objectId = context.getParameter("_" + OBJECT);
-            final String version = context.getParameter("_" + VERSION);
-            final String formId = context.getParameter("_" + FORM_ID);
-            String resultName = context.getParameter("_" + RESULT_NAME);
-            resultName = resultName == null ? RequestContext.RESULT : resultName;
-            final String override = context.getParameter("_" + RESULT_OVERRIDE);
-            String message = context.getParameter("_" + MESSAGE);
-
-            final ObjectAdapter adapter = context.getMappedObject(objectId);
-
-            final List<ObjectAssociation> fields = adapter.getSpecification().getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, adapter, where));
-
-            for (final ObjectAssociation objectAssociation : fields) {
-                if (objectAssociation.isVisible(session, adapter, where).isVetoed()) {
-                    throw new NotLoggedInException();
-                }
-            }
-
-            final FormState entryState = validateObject(context, adapter, fields);
-            final Version adapterVersion = adapter.getVersion();
-            final Version formVersion = context.getVersion(version);
-            if (formVersion != null && adapterVersion.different(formVersion)) {
-
-                IsisContext.getMessageBroker().addMessage("The " + adapter.getSpecification().getSingularName() + " was edited " + "by another user (" + adapterVersion.getUser() + "). Please  make your changes based on their changes.");
-
-                final String view = context.getParameter("_" + ERROR);
-                context.setRequestPath(view, Dispatcher.EDIT);
-
-                entryState.setForm(formId);
-                context.addVariable(ENTRY_FIELDS, entryState, Scope.REQUEST);
-                context.addVariable(resultName, objectId, Scope.REQUEST);
-                if (override != null) {
-                    context.addVariable(resultName, override, Scope.REQUEST);
-                }
-
-            } else if (entryState.isValid()) {
-                changeObject(context, adapter, entryState, fields);
-
-                if (adapter.isTransient()) {
-                    IsisContext.getPersistenceSession().makePersistent(adapter);
-                    context.unmapObject(adapter, Scope.REQUEST);
-                }
-
-                String view = context.getParameter("_" + VIEW);
-
-                final String id = context.mapObject(adapter, Scope.REQUEST);
-                context.addVariable(resultName, id, Scope.REQUEST);
-                if (override != null) {
-                    context.addVariable(resultName, override, Scope.REQUEST);
-                }
-
-                final int questionMark = view == null ? -1 : view.indexOf("?");
-                if (questionMark > -1) {
-                    final String params = view.substring(questionMark + 1);
-                    final int equals = params.indexOf("=");
-                    context.addVariable(params.substring(0, equals), params.substring(equals + 1), Scope.REQUEST);
-                    view = view.substring(0, questionMark);
-                }
-                context.setRequestPath(view);
-                if (message == null) {
-                    message = "Saved changes to " + adapter.getSpecification().getSingularName();
-                } else if (message.equals("")) {
-                    message = null;
-                }
-                if (message != null) {
-                    final MessageBroker messageBroker = IsisContext.getMessageBroker();
-                    messageBroker.addMessage(message);
-                }
-
-            } else {
-                final String view = context.getParameter("_" + ERROR);
-                context.setRequestPath(view, Dispatcher.EDIT);
-
-                entryState.setForm(formId);
-                context.addVariable(ENTRY_FIELDS, entryState, Scope.REQUEST);
-                context.addVariable(resultName, objectId, Scope.REQUEST);
-                if (override != null) {
-                    context.addVariable(resultName, override, Scope.REQUEST);
-                }
-
-                final MessageBroker messageBroker = IsisContext.getMessageBroker();
-                messageBroker.addWarning(entryState.getError());
-            }
-
-        } catch (final RuntimeException e) {
-            IsisContext.getMessageBroker().getMessages();
-            IsisContext.getMessageBroker().getWarnings();
-            IsisContext.getUpdateNotifier().clear();
-            IsisContext.getUpdateNotifier().clear();
-            throw e;
-        }
-    }
-
-    private FormState validateObject(final RequestContext context, final ObjectAdapter object, final List<ObjectAssociation> fields) {
-        final FormState formState = new FormState();
-        for (int i = 0; i < fields.size(); i++) {
-            final ObjectAssociation field = fields.get(i);
-            final String fieldId = field.getId();
-            String newEntry = context.getParameter(fieldId);
-            if (fields.get(i).isOneToManyAssociation()) {
-                continue;
-            }
-            if (fields.get(i).isVisible(IsisContext.getAuthenticationSession(), object, where).isVetoed()) {
-                continue;
-            }
-            if (field.isUsable(IsisContext.getAuthenticationSession(), object, where).isVetoed()) {
-                continue;
-            }
-
-            if (newEntry != null && newEntry.equals("-OTHER-")) {
-                newEntry = context.getParameter(fieldId + "-other");
-            }
-
-            if (newEntry == null) {
-                // TODO duplicated in EditObject; line 97
-                final ObjectSpecification spec = field.getSpecification();
-                if (spec.isOfType(IsisContext.getSpecificationLoader().loadSpecification(boolean.class)) || spec.isOfType(IsisContext.getSpecificationLoader().loadSpecification(Boolean.class))) {
-                    newEntry = FALSE;
-                } else {
-                    continue;
-                }
-            }
-            final FieldEditState fieldState = formState.createField(fieldId, newEntry);
-
-            Consent consent = null;
-            if (field.isMandatory() && (newEntry.equals("") || newEntry.equals("NULL"))) {
-                consent = new Veto(field.getName() + " required");
-                formState.setError("Not all fields have been set");
-            } else if (field.getSpecification().containsFacet(ParseableFacet.class)) {
-                try {
-                    final ParseableFacet facet = field.getSpecification().getFacet(ParseableFacet.class);
-                    final ObjectAdapter originalValue = field.get(object);
-                    Localization localization = IsisContext.getLocalization(); 
-                    final ObjectAdapter newValue = facet.parseTextEntry(originalValue, newEntry, localization); 
-                    consent = ((OneToOneAssociation) field).isAssociationValid(object, newValue);
-                    fieldState.setValue(newValue);
-                } catch (final TextEntryParseException e) {
-                    consent = new Veto(e.getMessage());
-                    // formState.setError("Not all fields have been entered correctly");
-                }
-
-            } else {
-                final ObjectAdapter associate = newEntry.equals("null") ? null : context.getMappedObject(newEntry);
-                if (associate != null) {
-                    IsisContext.getPersistenceSession().resolveImmediately(associate);
-                }
-                consent = ((OneToOneAssociation) field).isAssociationValid(object, associate);
-                fieldState.setValue(associate);
-
-            }
-            if (consent.isVetoed()) {
-                fieldState.setError(consent.getReason());
-                formState.setError("Not all fields have been entered correctly");
-            }
-        }
-
-        // TODO check the state of the complete object.
-        return formState;
-    }
-
-    private void changeObject(final RequestContext context, final ObjectAdapter object, final FormState editState, final List<ObjectAssociation> fields) {
-        for (int i = 0; i < fields.size(); i++) {
-            final FieldEditState field = editState.getField(fields.get(i).getId());
-            if (field == null) {
-                continue;
-            }
-            final String newEntry = field.getEntry();
-            final ObjectAdapter originalValue = fields.get(i).get(object);
-            final boolean isVisible = fields.get(i).isVisible(IsisContext.getAuthenticationSession(), object, where).isAllowed();
-            final boolean isUsable = fields.get(i).isUsable(IsisContext.getAuthenticationSession(), object, where).isAllowed();
-            final boolean bothEmpty = originalValue == null && newEntry.equals("");
-            final boolean bothSame = newEntry.equals(originalValue == null ? "" : originalValue.titleString());
-            if ((!isVisible || !isUsable) || bothEmpty || bothSame) {
-                if (fields.get(i).getSpecification().getFacet(ParseableFacet.class) == null) {
-                    // REVIEW restores object to loader
-                    context.getMappedObject(newEntry);
-                }
-                continue;
-            }
-
-            if (fields.get(i).getSpecification().containsFacet(ParseableFacet.class)) {
-                final ParseableFacet facet = fields.get(i).getSpecification().getFacet(ParseableFacet.class);
-                Localization localization = IsisContext.getLocalization(); 
-                final ObjectAdapter newValue = facet.parseTextEntry(originalValue, newEntry, localization);
-                ((OneToOneAssociation) fields.get(i)).set(object, newValue);
-            } else {
-                ((OneToOneAssociation) fields.get(i)).set(object, field.getValue());
-            }
-        }
-    }
-
-    @Override
-    public void init() {
-    }
-
-    @Override
-    public void debug(final DebugBuilder debug) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FieldEditState.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FieldEditState.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FieldEditState.java
deleted file mode 100644
index 70e6789..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FieldEditState.java
+++ /dev/null
@@ -1,57 +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.edit;
-
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-
-public class FieldEditState {
-    private final String entry;
-    private String reason;
-    private ObjectAdapter value;
-
-    public FieldEditState(final String entry) {
-        this.entry = entry;
-    }
-
-    public void setError(final String reason) {
-        this.reason = reason;
-    }
-
-    public boolean isEntryValid() {
-        return reason == null;
-    }
-
-    public String getEntry() {
-        return entry;
-    }
-
-    public String getError() {
-        return reason;
-    }
-
-    public ObjectAdapter getValue() {
-        return value;
-    }
-
-    public void setValue(final ObjectAdapter value) {
-        this.value = value;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FormState.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FormState.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FormState.java
deleted file mode 100644
index 7349837..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/FormState.java
+++ /dev/null
@@ -1,67 +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.edit;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-public class FormState {
-    private final Map<String, FieldEditState> fields = new HashMap<String, FieldEditState>();
-    private String error;
-    private String formId;
-
-    public FieldEditState createField(final String name, final String entry) {
-        final FieldEditState fieldEditState = new FieldEditState(entry);
-        fields.put(name, fieldEditState);
-        return fieldEditState;
-    }
-
-    public boolean isValid() {
-        final Iterator<FieldEditState> iterator = fields.values().iterator();
-        while (iterator.hasNext()) {
-            if (!iterator.next().isEntryValid()) {
-                return false;
-            }
-        }
-        return error == null;
-    }
-
-    public FieldEditState getField(final String name) {
-        return fields.get(name);
-    }
-
-    public void setError(final String error) {
-        this.error = error;
-    }
-
-    public String getError() {
-        return error;
-    }
-
-    public void setForm(final String formId) {
-        this.formId = formId;
-    }
-
-    public boolean isForForm(final String formId) {
-        return this.formId == null || this.formId.equals(formId);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/RemoveAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/RemoveAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/RemoveAction.java
deleted file mode 100644
index 1bd86a2..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/edit/RemoveAction.java
+++ /dev/null
@@ -1,116 +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.edit;
-
-import java.io.IOException;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.authentication.AnonymousSession;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-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;
-
-/**
- * Remove an element from a collection.
- */
-public class RemoveAction implements Action {
-    public static final String ACTION = "remove";
-
-    // REVIEW: confirm this rendering context
-    private final Where where = Where.OBJECT_FORMS;
-
-    @Override
-    public String getName() {
-        return ACTION;
-    }
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-        AuthenticationSession session = context.getSession();
-        if (session == null) {
-            session = new AnonymousSession();
-        }
-
-        final String parentId = context.getParameter(OBJECT);
-        final String rowId = context.getParameter(ELEMENT);
-
-        try {
-            final ObjectAdapter parent = context.getMappedObject(parentId);
-            final ObjectAdapter row = context.getMappedObject(rowId);
-
-            final String fieldName = context.getParameter(FIELD);
-            final ObjectAssociation field = parent.getSpecification().getAssociation(fieldName);
-            if (field == null) {
-                throw new ScimpiException("No field " + fieldName + " in " + parent.getSpecification().getFullIdentifier());
-            }
-            if (field.isVisible(IsisContext.getAuthenticationSession(), parent, where).isVetoed()) {
-                throw new ForbiddenException(field, ForbiddenException.VISIBLE);
-            }
-
-            ((OneToManyAssociation) field).removeElement(parent, row);
-
-            // TODO duplicated in EditAction
-            String view = context.getParameter(VIEW);
-            final String override = context.getParameter(RESULT_OVERRIDE);
-
-            String resultName = context.getParameter(RESULT_NAME);
-            resultName = resultName == null ? RequestContext.RESULT : resultName;
-
-            final String id = context.mapObject(parent, Scope.REQUEST);
-            context.addVariable(resultName, id, Scope.REQUEST);
-            if (override != null) {
-                context.addVariable(resultName, override, Scope.REQUEST);
-            }
-
-            final int questionMark = view == null ? -1 : view.indexOf("?");
-            if (questionMark > -1) {
-                final String params = view.substring(questionMark + 1);
-                final int equals = params.indexOf("=");
-                context.addVariable(params.substring(0, equals), params.substring(equals + 1), Scope.REQUEST);
-                view = view.substring(0, questionMark);
-            }
-            context.setRequestPath(view);
-            // TODO end of duplication
-
-        } catch (final RuntimeException e) {
-            IsisContext.getMessageBroker().getMessages();
-            IsisContext.getMessageBroker().getWarnings();
-            IsisContext.getUpdateNotifier().clear();
-            IsisContext.getUpdateNotifier().clear();
-            throw e;
-        }
-    }
-
-    @Override
-    public void init() {
-    }
-
-    @Override
-    public void debug(final DebugBuilder debug) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogonAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogonAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogonAction.java
deleted file mode 100644
index 52a15fe..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogonAction.java
+++ /dev/null
@@ -1,147 +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.logon;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.isis.applib.profiles.Localization;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
-import org.apache.isis.core.runtime.authentication.AuthenticationRequestPassword;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
-import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
-import org.apache.isis.viewer.scimpi.dispatcher.UserManager;
-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.util.MethodsUtils;
-
-
-// TODO this should work like EditAction so that logon page is repopulated
-public class LogonAction implements Action {
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-        final String username = context.getParameter("username");
-        final String password = context.getParameter("password");
-        final String actualFormId = context.getParameter("_" + FORM_ID);
-        final String expectedFormId = context.getParameter(LOGON_FORM_ID);
-        boolean isDomainLogon = expectedFormId != null && expectedFormId.equals(actualFormId);
-        boolean isValid;
-
-        AuthenticationSession session = null;
-        if (username.length() == 0 || password.length() == 0) {
-            isValid = false;
-        } else {
-            if (isDomainLogon) {
-                final String objectId = context.getParameter(LOGON_OBJECT);
-                final String scope = context.getParameter(LOGON_SCOPE);
-                final String methodName = context.getParameter(LOGON_METHOD);
-                String resultName = context.getParameter(LOGON_RESULT_NAME);
-                resultName = resultName == null ? "_" + USER : resultName;
-
-                final ObjectAdapter object = MethodsUtils.findObject(context, objectId);
-                final ObjectAction action = MethodsUtils.findAction(object, methodName);
-                final int parameterCount = action.getParameterCount();
-                final ObjectAdapter[] parameters = new ObjectAdapter[parameterCount];
-                List<ObjectActionParameter> parameters2 = action.getParameters();
-                if (parameters.length != 2) {
-                    throw new ScimpiException("Expected two parameters for the log-on method: " + methodName);
-                }
-
-                Localization localization = IsisContext.getLocalization(); 
-                ParseableFacet facet = parameters2.get(0).getSpecification().getFacet(ParseableFacet.class);
-                parameters[0] = facet.parseTextEntry(null, username, localization);
-                facet = parameters2.get(1).getSpecification().getFacet(ParseableFacet.class);
-                parameters[1] = facet.parseTextEntry(null, password, localization);
-                final ObjectAdapter result = action.execute(object, parameters);
-                isValid = result != null;
-                if (isValid) {
-                    Scope scope2 = scope == null ? Scope.SESSION : RequestContext.scope(scope);
-                    final String resultId = context.mapObject(result, scope2);
-                    context.addVariable(resultName, resultId, scope);
-                    context.addVariable("_username", username, Scope.SESSION);
-                    
-                    context.clearVariable(LOGON_OBJECT, Scope.SESSION);
-                    context.clearVariable(LOGON_METHOD, Scope.SESSION);
-                    context.clearVariable(LOGON_RESULT_NAME, Scope.SESSION);
-                    context.clearVariable(LOGON_SCOPE, Scope.SESSION);
-                    context.clearVariable(PREFIX + "isis-user", Scope.SESSION);
-                    context.clearVariable(LOGON_FORM_ID, Scope.SESSION);
-                }
-                session = context.getSession();
-            } else {
-                session = UserManager.authenticate(new AuthenticationRequestPassword(username, password));
-                isValid = session != null;
-            }
-        }
-
-        String view;
-        if (!isValid) {
-            final FormState formState = new FormState();
-            formState.setForm(actualFormId);
-            formState.setError("Failed to login. Check the username and ensure that your password was entered correctly");
-            FieldEditState fieldState = formState.createField("username", username);
-            if (username.length() == 0) {
-                fieldState.setError("User Name required");
-            }
-            fieldState = formState.createField("password", password);
-            if (password.length() == 0) {
-                fieldState.setError("Password required");
-            }
-            if (username.length() == 0 || password.length() == 0) {
-                formState.setError("Both the user name and password must be entered");
-            }
-            context.addVariable(ENTRY_FIELDS, formState, Scope.REQUEST);
-
-            view = context.getParameter(ERROR);
-            context.setRequestPath("/" + view, Dispatcher.ACTION);
-        } else {
-            context.setSession(session);
-            context.startHttpSession();
-            context.setUserAuthenticated(true);
-            view = context.getParameter(VIEW);
-            if (view == null) {
-                // REVIEW this is duplicated in Logon.java
-                view = "start." + Dispatcher.EXTENSION;
-            }
-            context.redirectTo(view);
-        }
-    }
-
-    @Override
-    public String getName() {
-        return "logon";
-    }
-
-    @Override
-    public void init() {}
-
-    @Override
-    public void debug(final DebugBuilder debug) {}
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogoutAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogoutAction.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogoutAction.java
deleted file mode 100644
index 219b5b4..0000000
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/logon/LogoutAction.java
+++ /dev/null
@@ -1,71 +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.logon;
-
-import java.io.IOException;
-
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.debug.DebugBuilder;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.scimpi.dispatcher.Action;
-import org.apache.isis.viewer.scimpi.dispatcher.UserManager;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;
-
-public class LogoutAction implements Action {
-
-    public static void logoutUser(final RequestContext context) {
-        if (context.isUserAuthenticated()) {
-            final AuthenticationSession session = context.getSession();
-            if (session != null) {
-                IsisContext.getUpdateNotifier().clear();
-                UserManager.logoffUser(session);
-            }
-            context.endHttpSession();
-            context.setUserAuthenticated(false);
-        }
-        context.clearVariables(Scope.SESSION);
-    }
-
-    @Override
-    public String getName() {
-        return "logout";
-    }
-
-    @Override
-    public void init() {
-    }
-
-    @Override
-    public void process(final RequestContext context) throws IOException {
-        logoutUser(context);
-        
-        String view = context.getParameter("view");
-        if (view == null) {
-            view = context.getContextPath();
-        }
-        context.redirectTo(view);
-    }
-
-    @Override
-    public void debug(final DebugBuilder debug) {
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Attributes.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Attributes.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Attributes.java
new file mode 100644
index 0000000..86fd17e
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Attributes.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.processor;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.htmlparser.Attribute;
+import org.htmlparser.nodes.TagNode;
+
+import org.apache.isis.viewer.scimpi.dispatcher.context.PropertyException;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
+
+public class Attributes {
+    private static final String TRUE = " true yes on ";
+    private static final String FALSE = " false no off ";
+    private final TagNode tagNode;
+    private final Request context;
+
+    public Attributes(final TagNode tagNode, final Request context) {
+        this.tagNode = tagNode;
+        this.context = context;
+    }
+
+    public boolean isPropertySet(final String name) {
+        final String attribute = tagNode.getAttribute(name);
+        int end = attribute.length() - 1;
+        final int pos = attribute.indexOf(':');
+        end = pos == -1 ? end : pos;
+        final String variabelName = attribute.substring(2, end);
+        final Object value = context.getVariable(variabelName);
+        return value != null;
+        // return attribute != null &&
+        // !context.replaceVariables(attribute).equals("");
+    }
+
+    public boolean isPropertySpecified(final String name) {
+        final String attribute = tagNode.getAttribute(name);
+        return attribute != null;
+    }
+
+    public String getOptionalProperty(final String name, final boolean ensureVariablesExists) {
+        return getOptionalProperty(name, null, ensureVariablesExists);
+    }
+
+    public String getOptionalProperty(final String name, final String defaultValue, final boolean ensureVariablesExists) {
+        final String attribute = tagNode.getAttribute(name);
+        return attribute == null ? defaultValue : context.replaceVariables(attribute);
+    }
+
+    public String getRequiredProperty(final String name, final boolean ensureVariablesExists) {
+        final String attribute = tagNode.getAttribute(name);
+        if (attribute == null) {
+            throw new RequiredPropertyException("Missing property: " + name);
+        } else if (attribute.equals("")) {
+            throw new RequiredPropertyException("Property not set: " + name);
+        } else {
+            return context.replaceVariables(attribute);
+        }
+    }
+
+    public String[] getPropertyNames(final String excluding[]) {
+        final Vector attributes = tagNode.getAttributesEx();
+        final String[] names = new String[attributes.size()];
+        int i = 0;
+        names: for (final Enumeration e = attributes.elements(); e.hasMoreElements();) {
+            final String name = ((Attribute) e.nextElement()).getName();
+            if (name == null) {
+                continue;
+            }
+            for (int j = 0; j < excluding.length; j++) {
+                if (name.equals(excluding[j])) {
+                    continue names;
+                }
+            }
+            if (tagNode.getAttribute(name) != null) {
+                names[i++] = name;
+            }
+        }
+
+        final String[] array = new String[i];
+        System.arraycopy(names, 0, array, 0, i);
+        return array;
+    }
+
+    @Override
+    public String toString() {
+        return tagNode.toHtml(); // getAttributesEx().toString();
+    }
+
+    public boolean isRequested(final String name) {
+        return isRequested(name, false);
+    }
+
+    public boolean isRequested(final String name, final boolean defaultValue) {
+        final String flag = getOptionalProperty(name, true);
+        if (flag == null) {
+            return defaultValue;
+        } else {
+            return isTrue(flag);
+        }
+    }
+
+    public static boolean isTrue(final String flag) {
+        final String value = " " + flag.toLowerCase().trim() + " ";
+        if (TRUE.indexOf(value) >= 0) {
+            return true;
+        } else if (FALSE.indexOf(value) >= 0) {
+            return false;
+        } else {
+            throw new PropertyException("Illegal flag value: " + flag);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/BlockContent.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/BlockContent.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/BlockContent.java
new file mode 100644
index 0000000..0d91bdf
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/BlockContent.java
@@ -0,0 +1,23 @@
+/*
+ *  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.processor;
+
+public interface 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/processor/ElementContentProcessor.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementContentProcessor.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementContentProcessor.java
new file mode 100644
index 0000000..65e0bcf
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementContentProcessor.java
@@ -0,0 +1,25 @@
+/*
+ *  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.processor;
+
+
+public interface ElementContentProcessor extends ElementProcessor {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementProcessor.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementProcessor.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementProcessor.java
new file mode 100644
index 0000000..37fa0e1
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ElementProcessor.java
@@ -0,0 +1,29 @@
+/*
+ *  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.processor;
+
+
+public interface ElementProcessor {
+
+    String getName();
+
+    void process(TagProcessor tagProcessor);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlFileParser.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlFileParser.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlFileParser.java
index c7f2476..354af87 100644
--- a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlFileParser.java
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlFileParser.java
@@ -33,13 +33,8 @@ import org.htmlparser.lexer.Page;
 import org.htmlparser.nodes.TagNode;
 import org.htmlparser.util.ParserException;
 
-import org.apache.isis.viewer.scimpi.dispatcher.ElementProcessor;
-import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
-import org.apache.isis.viewer.scimpi.dispatcher.action.Attributes;
-import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
-import org.apache.isis.viewer.scimpi.dispatcher.view.HtmlSnippet;
-import org.apache.isis.viewer.scimpi.dispatcher.view.Snippet;
-import org.apache.isis.viewer.scimpi.dispatcher.view.SwfTag;
+import org.apache.isis.viewer.scimpi.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.context.Request;
 
 public class HtmlFileParser {
     private static final Logger LOG = Logger.getLogger(HtmlFileParser.class);
@@ -49,14 +44,14 @@ public class HtmlFileParser {
         this.processors = processors;
     }
 
-    public Stack<Snippet> parseHtmlFile(final String filePath, final RequestContext context) {
+    public Stack<Snippet> parseHtmlFile(final String filePath, final Request context) {
         final Stack<Snippet> tagsBeforeContent = new Stack<Snippet>();
         final Stack<Snippet> tagsAfterContent = new Stack<Snippet>();
         parseHtmlFile("/", filePath, context, tagsBeforeContent, tagsAfterContent);
         return tagsBeforeContent;
     }
 
-    public void parseHtmlFile(final String parentPath, final String filePath, final RequestContext context, final Stack<Snippet> allTags, final Stack<Snippet> tagsForPreviousTemplate) {
+    public void parseHtmlFile(final String parentPath, final String filePath, final Request context, final Stack<Snippet> allTags, final Stack<Snippet> tagsForPreviousTemplate) {
         LOG.debug("parent/file: " + parentPath + " & " + filePath);
         final File directory = filePath.startsWith("/") ? new File(".") : new File(parentPath);
         final File loadFile = new File(directory.getParentFile(), filePath);

http://git-wip-us.apache.org/repos/asf/isis/blob/49518c89/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlSnippet.java
----------------------------------------------------------------------
diff --git a/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlSnippet.java b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlSnippet.java
new file mode 100644
index 0000000..2e98c71
--- /dev/null
+++ b/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/HtmlSnippet.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.processor;
+
+public class HtmlSnippet implements Snippet {
+    private final StringBuffer html = new StringBuffer();
+    private boolean containsVariable;
+    private final String lineNumbers;
+    private final String path;
+
+    public HtmlSnippet(final String lineNumbers, final String path) {
+        this.lineNumbers = lineNumbers;
+        this.path = path;
+    }
+
+    public void append(final String html) {
+        this.html.append(html);
+        containsVariable |= html.indexOf("${") >= 0;
+    }
+
+    @Override
+    public String getHtml() {
+        return html.toString();
+    }
+
+    public boolean isContainsVariable() {
+        return containsVariable;
+    }
+
+    @Override
+    public String errorAt() {
+        return path + ":" + lineNumbers;
+    }
+}