You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/03/30 17:43:37 UTC

[08/59] [abbrv] isis git commit: ISIS-720: mothballing scimpi

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ProcessorLookup.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ProcessorLookup.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ProcessorLookup.java
new file mode 100644
index 0000000..36c1920
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/ProcessorLookup.java
@@ -0,0 +1,256 @@
+/*
+ *  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.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeSet;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.viewer.scimpi.dispatcher.ElementProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.debug.DebugUsersView;
+import org.apache.isis.viewer.scimpi.dispatcher.debug.ErrorDetails;
+import org.apache.isis.viewer.scimpi.dispatcher.debug.ErrorMessage;
+import org.apache.isis.viewer.scimpi.dispatcher.debug.ErrorReference;
+import org.apache.isis.viewer.scimpi.dispatcher.view.HelpLink;
+import org.apache.isis.viewer.scimpi.dispatcher.view.History;
+import org.apache.isis.viewer.scimpi.dispatcher.view.VersionNumber;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.ActionButton;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.ActionForm;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.ActionLink;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.Methods;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.Parameter;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.RunAction;
+import org.apache.isis.viewer.scimpi.dispatcher.view.action.Services;
+import org.apache.isis.viewer.scimpi.dispatcher.view.collection.Collection;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.DebugAccessCheck;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.DebugCollectionView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.DebugObjectView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.DebuggerLink;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.Diagnostics;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.Log;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.LogLevel;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.Members;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.ShowDebug;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.Specification;
+import org.apache.isis.viewer.scimpi.dispatcher.view.debug.ThrowException;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.AddMessage;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.AddWarning;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.Errors;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.Feedback;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.FieldLabel;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.FieldValue;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.GetField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.IncludeObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.ListView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.LongFormView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.Messages;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.SelectedObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.ShortFormView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.TableBuilder;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.TableCell;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.TableEmpty;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.TableHeader;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.TableRow;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.TableView;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.Title;
+import org.apache.isis.viewer.scimpi.dispatcher.view.display.Warnings;
+import org.apache.isis.viewer.scimpi.dispatcher.view.edit.EditObject;
+import org.apache.isis.viewer.scimpi.dispatcher.view.edit.FormEntry;
+import org.apache.isis.viewer.scimpi.dispatcher.view.edit.FormField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.edit.HiddenField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.edit.RadioListField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.edit.Selector;
+import org.apache.isis.viewer.scimpi.dispatcher.view.field.ExcludeField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.field.IncludeField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.field.LinkField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.logon.Logoff;
+import org.apache.isis.viewer.scimpi.dispatcher.view.logon.Logon;
+import org.apache.isis.viewer.scimpi.dispatcher.view.logon.RestrictAccess;
+import org.apache.isis.viewer.scimpi.dispatcher.view.logon.Secure;
+import org.apache.isis.viewer.scimpi.dispatcher.view.logon.User;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.BlockDefine;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.BlockUse;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Commit;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.ContentTag;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.CookieValue;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.DefaultValue;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.EditLink;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.EndSession;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Forward;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.GetCookie;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Import;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.InitializeFromCookie;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.InitializeFromResult;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Localization;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Mark;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.NewActionLink;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.ObjectLink;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.PageTitle;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Redirect;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.RemoveElement;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.ScopeTag;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.SetCookie;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.SetCookieFromField;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.SetFieldFromCookie;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.SetLocalization;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.SimpleButton;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.StartSession;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.TemplateTag;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Unless;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.Variable;
+import org.apache.isis.viewer.scimpi.dispatcher.view.simple.When;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.ActionName;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.CountElements;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.ElementType;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.FieldName;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.ParameterName;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.TitleString;
+import org.apache.isis.viewer.scimpi.dispatcher.view.value.Type;
+
+public class ProcessorLookup {
+    private final Map<String, ElementProcessor> swfElementProcessors = new HashMap<String, ElementProcessor>();
+
+    public void init() {
+        addElementProcessor(new ActionLink());
+        addElementProcessor(new ActionButton());
+        addElementProcessor(new ActionForm());
+        addElementProcessor(new ActionName());
+        addElementProcessor(new AddMessage());
+        addElementProcessor(new AddWarning());
+        addElementProcessor(new BlockDefine());
+        addElementProcessor(new BlockUse());
+        addElementProcessor(new History());
+        addElementProcessor(new Collection());
+        addElementProcessor(new Commit());
+        addElementProcessor(new ContentTag());
+        addElementProcessor(new CountElements());
+        addElementProcessor(new Diagnostics());
+        addElementProcessor(new DebugAccessCheck());
+        addElementProcessor(new DebugCollectionView()); 
+        addElementProcessor(new DebuggerLink());
+        addElementProcessor(new DebugObjectView()); 
+        addElementProcessor(new DebugUsersView());
+        addElementProcessor(new DefaultValue());
+        addElementProcessor(new EditLink());
+        addElementProcessor(new EditObject());
+        addElementProcessor(new ElementType());
+        addElementProcessor(new Errors());
+        addElementProcessor(new ErrorDetails()); 
+        addElementProcessor(new ErrorMessage()); 
+        addElementProcessor(new ErrorReference());
+        addElementProcessor(new ExcludeField());
+        addElementProcessor(new Feedback());
+        addElementProcessor(new FieldLabel());
+        addElementProcessor(new FieldName());
+        addElementProcessor(new FieldValue());
+        addElementProcessor(new FormField());
+        addElementProcessor(new FormEntry());
+        addElementProcessor(new Forward());
+        addElementProcessor(new GetField());
+        addElementProcessor(new HelpLink());
+        addElementProcessor(new HiddenField());
+        addElementProcessor(new Import());
+        addElementProcessor(new IncludeObject());
+        addElementProcessor(new IncludeField());
+        addElementProcessor(new InitializeFromCookie());
+        addElementProcessor(new InitializeFromResult());
+        addElementProcessor(new Log());
+        addElementProcessor(new LogLevel());
+        addElementProcessor(new Logon());
+        addElementProcessor(new Logoff());
+        addElementProcessor(new LongFormView());
+        addElementProcessor(new LinkField());
+        addElementProcessor(new ListView());
+        addElementProcessor(new NewActionLink());
+        addElementProcessor(new Mark());
+        addElementProcessor(new Members());
+        addElementProcessor(new Messages());
+        addElementProcessor(new Methods());
+        addElementProcessor(new ObjectLink());
+        addElementProcessor(new PageTitle());
+        addElementProcessor(new Parameter());
+        addElementProcessor(new ParameterName());
+        addElementProcessor(new RadioListField());
+        addElementProcessor(new Redirect());
+        addElementProcessor(new RemoveElement());
+        addElementProcessor(new VersionNumber());
+        addElementProcessor(new RunAction());
+        addElementProcessor(new RestrictAccess());
+        addElementProcessor(new ScopeTag());
+        addElementProcessor(new Secure());
+        addElementProcessor(new SelectedObject());
+        addElementProcessor(new Selector());
+        addElementProcessor(new Services());
+        addElementProcessor(new ShortFormView());
+        addElementProcessor(new ShowDebug());
+        addElementProcessor(new SimpleButton());
+        addElementProcessor(new Specification());
+        addElementProcessor(new TableCell());
+        addElementProcessor(new TableView());
+        addElementProcessor(new TableBuilder());
+        addElementProcessor(new TableEmpty());
+        addElementProcessor(new TableRow());
+        addElementProcessor(new TableHeader());
+        addElementProcessor(new TemplateTag());
+        addElementProcessor(new Title());
+        addElementProcessor(new TitleString());
+        addElementProcessor(new ThrowException());
+        addElementProcessor(new Type());
+        addElementProcessor(new User());
+        addElementProcessor(new Unless());
+        addElementProcessor(new Variable());
+        addElementProcessor(new Warnings());
+        addElementProcessor(new When());
+
+        addElementProcessor(new StartSession());
+        addElementProcessor(new EndSession());
+
+        addElementProcessor(new CookieValue());
+        addElementProcessor(new SetCookie());
+        addElementProcessor(new GetCookie());
+        addElementProcessor(new SetCookieFromField());
+        addElementProcessor(new SetFieldFromCookie());
+        
+        // new, alpha, processors
+        addElementProcessor(new Localization());
+        addElementProcessor(new SetLocalization());
+    }
+
+    public void addElementProcessor(final ElementProcessor action) {
+        swfElementProcessors.put("SWF:" + action.getName().toUpperCase(), action);
+    }
+
+    public void debug(final DebugBuilder debug) {
+        debug.startSection("Recognised tags");
+        final Iterator<String> it2 = new TreeSet<String>(swfElementProcessors.keySet()).iterator();
+        while (it2.hasNext()) {
+            final String name = it2.next();
+            debug.appendln(name.toLowerCase(), swfElementProcessors.get(name));
+        }
+        debug.endSection();
+    }
+
+    public ElementProcessor getFor(final String name) {
+        return swfElementProcessors.get(name);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Request.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Request.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Request.java
new file mode 100644
index 0000000..118ff9b
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/Request.java
@@ -0,0 +1,324 @@
+/*
+ *  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.Stack;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.viewer.scimpi.dispatcher.BlockContent;
+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;
+
+public class Request implements PageWriter {
+
+    public class RepeatMarker {
+        private final int index;
+
+        private RepeatMarker(final int index) {
+            this.index = index;
+        }
+
+        public void repeat() {
+            Request.this.index = index;
+        }
+    }
+
+    private static Logger LOG = LoggerFactory.getLogger(Request.class);
+    public static final boolean ENSURE_VARIABLES_EXIST = true;
+    public static final boolean NO_VARIABLE_CHECKING = false;
+    private static Encoder encoder;
+
+    public static Encoder getEncoder() {
+        return encoder;
+    }
+
+    private final RequestContext context;
+    private final Stack<Snippet> snippets;
+    private final Stack<StringBuffer> buffers;
+    private final Stack<BlockContent> blocks;
+    private final ProcessorLookup processors;
+    private int nextFormId;
+    private int index = -1;
+    private final String path;
+
+    public Request(final String path, final RequestContext context, final Encoder encoder, final Stack<Snippet> snippets, final ProcessorLookup processors) {
+        this.path = path;
+        this.context = context;
+        Request.encoder = encoder;
+        this.snippets = snippets;
+        this.processors = processors;
+
+        buffers = new Stack<StringBuffer>();
+        blocks = new Stack<BlockContent>();
+        pushNewBuffer();
+    }
+
+    public void processNextTag() {
+        while (index < snippets.size() - 1) {
+            index++;
+            final Snippet snippet = snippets.get(index);
+            if (snippet instanceof HtmlSnippet) {
+                appendSnippet((HtmlSnippet) snippet);
+            } else {
+                final SwfTag tag = (SwfTag) snippet;
+                final String name = tag.getName();
+                final ElementProcessor processor = processors.getFor(name);
+                process(tag, processor);
+                if (context.isAborted()) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private void appendSnippet(final HtmlSnippet snippet) {
+        String html = snippet.getHtml();
+        try {
+            if (snippet.isContainsVariable()) {
+                html = context.replaceVariables(html);
+            }
+            appendHtml(html);
+        } catch (final TagProcessingException e) {
+            throw e;
+        } catch (final RuntimeException e) {
+            final String replace = "<";
+            final String withReplacement = "&lt;";
+            html = html.replaceAll(replace, withReplacement);
+
+            throw new TagProcessingException("Error while processing html block at " + snippet.errorAt() + " - " + e.getMessage(), html, e);
+        }
+    }
+
+    @Override
+    public void appendAsHtmlEncoded(final String string) {
+        appendHtml(encodeHtml(string));
+        // appendHtml(string);
+    }
+
+    @Override
+    public void appendHtml(final String html) {
+        final StringBuffer buffer = buffers.peek();
+        buffer.append(html);
+    }
+
+    public void appendDebug(final String line) {
+        context.appendDebugTrace(encodeHtml(line));
+    }
+
+    private String encodeHtml(final String text) {
+        return encoder.encoder(text);
+    }
+
+    public void appendTruncated(String text, final int truncateTo) {
+        if (truncateTo > 0 && text.length() > truncateTo) {
+            text = text.substring(0, truncateTo) + "...";
+        }
+        appendAsHtmlEncoded(text);
+    }
+
+    private void process(final SwfTag tag, final ElementProcessor processor) {
+        try {
+            LOG.debug("processing " + processor.getName() + " " + tag);
+            appendDebug("\n" + tag.debug());
+            if (tag.getType() == SwfTag.END) {
+                throw new TagProcessingException(tag.errorAt() + " - end tag mistaken for a start tag", tag.toString());
+            }
+            processor.process(this);
+        } catch (final TagProcessingException e) {
+            throw e;
+        } catch (final RuntimeException e) {
+            throw new TagProcessingException("Error while processing " + tag.getName().toLowerCase() + " element at " + tag.errorAt() + " - " + e.getMessage(), tag.toString(), e);
+        }
+    }
+
+    public void processUtilCloseTag() {
+        final SwfTag tag = getTag();
+        if (tag.getType() == SwfTag.EMPTY) {
+            return;
+        }
+        while (index < snippets.size() - 1) {
+            index++;
+            final Snippet snippet = snippets.get(index);
+            if (snippet instanceof HtmlSnippet) {
+                appendSnippet((HtmlSnippet) snippet);
+            } else {
+                final SwfTag nextTag = (SwfTag) snippet;
+                if (tag.getName().equals(nextTag.getName())) {
+                    if (nextTag.getType() == SwfTag.START) {
+                    } else {
+                        return;
+                    }
+                }
+                final String name = nextTag.getName();
+                if (nextTag.getType() == SwfTag.END && !tag.getName().equals(name)) {
+                    throw new TagProcessingException("Expected " + nextTag.getName().toLowerCase() + " tag but found " + tag.getName().toLowerCase() + " tag at " + nextTag.errorAt(), tag.toString());
+                }
+                final ElementProcessor processor = processors.getFor(name);
+                process(nextTag, processor);
+            }
+        }
+    }
+
+    public void skipUntilClose() {
+        final SwfTag tag = getTag();
+        if (tag.getType() == SwfTag.EMPTY) {
+            if (context.isDebug()) {
+                appendHtml("<!-- " + "skipped " + tag + " -->");
+            }
+            return;
+        }
+        int depth = 1;
+        while (index < snippets.size() - 1) {
+            index++;
+            final Snippet snippet = snippets.get(index);
+            if (snippet instanceof SwfTag) {
+                final SwfTag nextTag = (SwfTag) snippet;
+                if (tag.getName().equals(nextTag.getName())) {
+                    if (nextTag.getType() == SwfTag.START) {
+                        depth++;
+                    } else {
+                        depth--;
+                        if (depth == 0) {
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void closeEmpty() {
+        final SwfTag tag = getTag();
+        if (tag.getType() == SwfTag.EMPTY) {
+            return;
+        }
+        if (index < snippets.size()) {
+            final Snippet snippet = snippets.get(index);
+            if (snippet instanceof SwfTag) {
+                final SwfTag nextTag = (SwfTag) snippet;
+                if (nextTag.getType() == SwfTag.EMPTY) {
+                    return;
+                }
+            }
+        }
+        throw new ScimpiException("Empty tag not closed");
+    }
+
+    public void pushNewBuffer() {
+        final StringBuffer buffer = new StringBuffer();
+        buffers.push(buffer);
+    }
+
+    public String popBuffer() {
+        final String content = buffers.pop().toString();
+        return content;
+    }
+
+    public SwfTag getTag() {
+        return (SwfTag) snippets.get(index);
+    }
+
+    public RequestContext getContext() {
+        return context;
+    }
+
+    // TODO rename to pushBlock()
+    public void setBlockContent(final BlockContent content) {
+        blocks.add(content);
+    }
+
+    public BlockContent popBlockContent() {
+        return blocks.pop();
+    }
+
+    public BlockContent getBlockContent() {
+        return blocks.peek();
+    }
+
+    public String getViewPath() {
+        return path;
+    }
+
+    public String nextFormId() {
+        return String.valueOf(nextFormId++);
+    }
+
+    public String getOptionalProperty(final String name, final String defaultValue) {
+        return getOptionalProperty(name, defaultValue, true);
+    }
+
+    public String getOptionalProperty(final String name, final String defaultValue, final boolean ensureVariablesExists) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.getOptionalProperty(name, defaultValue, ensureVariablesExists);
+    }
+
+    public String getOptionalProperty(final String name) {
+        return getOptionalProperty(name, true);
+    }
+
+    public String getOptionalProperty(final String name, final boolean ensureVariablesExists) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.getOptionalProperty(name, ensureVariablesExists);
+    }
+
+    public Attributes getAttributes() {
+        return getTag().getAttributes();
+    }
+
+    public String getRequiredProperty(final String name) {
+        return getRequiredProperty(name, true);
+    }
+
+    public String getRequiredProperty(final String name, final boolean ensureVariablesExists) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.getRequiredProperty(name, ensureVariablesExists);
+    }
+
+    public boolean isRequested(final String name) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.isRequested(name);
+    }
+
+    public boolean isRequested(final String name, final boolean defaultValue) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.isRequested(name, defaultValue);
+    }
+
+    public boolean isPropertySet(final String name) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.isPropertySet(name);
+    }
+
+    public boolean isPropertySpecified(final String name) {
+        final Attributes attributes = getTag().getAttributes();
+        return attributes.isPropertySpecified(name);
+    }
+
+    public RepeatMarker createMarker() {
+        return new RepeatMarker(index);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/SimpleEncoder.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/SimpleEncoder.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/SimpleEncoder.java
new file mode 100644
index 0000000..8b7a2d5
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/SimpleEncoder.java
@@ -0,0 +1,32 @@
+/*
+ *  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 org.apache.commons.lang.StringEscapeUtils;
+
+public class SimpleEncoder implements Encoder {
+
+    @Override
+    public String encoder(final String text) {
+        return StringEscapeUtils.escapeHtml(text);
+        // text.replace("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">",
+        // "&gt;").replace("\"", "&quot;");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/TagProcessingException.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/TagProcessingException.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/TagProcessingException.java
new file mode 100644
index 0000000..d9a8a60
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/processor/TagProcessingException.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.scimpi.dispatcher.processor;
+
+import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
+
+public class TagProcessingException extends ScimpiException {
+    private static final long serialVersionUID = 1L;
+    private String context;
+
+    public TagProcessingException() {
+        super();
+    }
+
+    public TagProcessingException(final String message, final String context, final Throwable cause) {
+        super(message, cause);
+        this.context = context;
+    }
+
+    public TagProcessingException(final String message, final String context) {
+        super(message);
+        this.context = context;
+    }
+
+    public TagProcessingException(final Throwable cause) {
+        super(cause);
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    @Override
+    public String getMessage() {
+        return super.getMessage() + "\n" + getContext();
+    }
+
+    @Override
+    public String getHtmlMessage() {
+        return super.getMessage() + "<pre>" + getContext() + "</pre>";
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/util/MethodsUtils.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/util/MethodsUtils.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/util/MethodsUtils.java
new file mode 100644
index 0000000..a6ae574
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/util/MethodsUtils.java
@@ -0,0 +1,154 @@
+/*
+ *  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.util;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.services.ServiceUtil;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.core.runtime.system.session.IsisSession;
+import org.apache.isis.viewer.scimpi.dispatcher.DispatchException;
+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;
+
+public class MethodsUtils {
+    public static final String SERVICE_PREFIX = "service:";
+
+    public static Consent canRunMethod(final ObjectAdapter target, final ObjectAction action, final ObjectAdapter[] parameters) {
+        final Consent consent = action.isProposedArgumentSetValid(target, parameters == null ? new ObjectAdapter[0] : parameters);
+        return consent;
+    }
+
+    public static boolean runMethod(final RequestContext context, final ObjectAction action, final ObjectAdapter target, final ObjectAdapter[] parameters, String variable, Scope scope) {
+        scope = scope == null ? Scope.REQUEST : scope;
+        variable = variable == null ? RequestContext.RESULT : variable;
+
+        final ObjectAdapter result = action.execute(target, parameters == null ? new ObjectAdapter[0] : parameters);
+        if (result == null) {
+            return false;
+        } else {
+            final String mappedId = context.mapObject(result, scope);
+            context.addVariable(variable, mappedId, scope);
+            // context.addVariable(variable + "_type",
+            // action.getFacet(TypeOfFacet.class), scope);
+            return true;
+        }
+    }
+
+    public static boolean runMethod(final RequestContext context, final ObjectAction action, final ObjectAdapter target, final ObjectAdapter[] parameters) {
+        return runMethod(context, action, target, parameters, null, null);
+    }
+
+    public static ObjectAction findAction(final ObjectAdapter object, final String methodName) {
+        if (object == null) {
+            throw new ScimpiException("Object not specified when looking for " + methodName);
+        }
+
+        final List<ObjectAction> actions = object.getSpecification().getObjectActions(Contributed.INCLUDED);
+        final ObjectAction action = findAction(actions, methodName);
+        /*
+         * if (action == null) { actions =
+         * object.getSpecification().getServiceActionsFor(ObjectActionType.USER,
+         * ObjectActionType.EXPLORATION, ObjectActionType.DEBUG); action =
+         * findAction(actions, methodName); }
+         */
+        if (action == null) {
+            throw new DispatchException("Failed to find action " + methodName + " on " + object);
+        }
+        return action;
+    }
+
+    private static ObjectAction findAction(final List<ObjectAction> actions, final String methodName) {
+        for (int i = 0; i < actions.size(); i++) {
+            final ObjectAction objectAction = actions.get(i);
+            if (objectAction.getId().equals(methodName)) {
+                return objectAction;
+            }
+        }
+        return null;
+    }
+
+    public static ObjectAdapter findObject(final RequestContext context, String objectId) {
+        if (objectId == null) {
+            objectId = context.getStringVariable(RequestContext.RESULT);
+        }
+
+        if (objectId != null && objectId.startsWith(SERVICE_PREFIX)) {
+            final String serviceId = objectId.substring(SERVICE_PREFIX.length());
+            final List<ObjectAdapter> serviceAdapters = getPersistenceSession().getServices();
+            for (final ObjectAdapter serviceAdapter : serviceAdapters) {
+                final Object service = serviceAdapter.getObject();
+                if (ServiceUtil.id(service).equals(serviceId.trim())) {
+                    final ObjectAdapter adapter = getAdapterManager().getAdapterFor(service);
+                    return adapter;
+                }
+            }
+            throw new DispatchException("Failed to find service " + serviceId);
+        } else {
+            return context.getMappedObject(objectId);
+        }
+    }
+
+    public static boolean isVisible(final ObjectAdapter object, final ObjectAction action, Where where) {
+        return action.isVisible(getAuthenticationSession(), object, where).isAllowed();
+    }
+
+    public static String isUsable(final ObjectAdapter object, final ObjectAction action, Where where) {
+        final Consent usable = action.isUsable(getAuthenticationSession(), object, where);
+        final boolean isUsable = getSession() != null && usable.isAllowed();
+        return isUsable ? null : usable.getReason();
+    }
+
+    public static boolean isVisibleAndUsable(final ObjectAdapter object, final ObjectAction action, Where where) {
+        AuthenticationSession authenticatedSession = getAuthenticationSession();
+        final boolean isVisible = action.isVisible(authenticatedSession, object, where).isAllowed();
+        final boolean isUsable = getSession() != null && action.isUsable(authenticatedSession, object, where).isAllowed();
+        final boolean isVisibleAndUsable = isVisible && isUsable;
+        return isVisibleAndUsable;
+    }
+
+    private static AuthenticationSession getAuthenticationSession() {
+        return IsisContext.getAuthenticationSession();
+    }
+
+    private static IsisSession getSession() {
+        return IsisContext.getSession();
+    }
+
+    private static AdapterManager getAdapterManager() {
+        return getPersistenceSession().getAdapterManager();
+    }
+
+    private static PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/HelpLink.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/HelpLink.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/HelpLink.java
new file mode 100644
index 0000000..477828d
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/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;
+
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+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;
+
+public class HelpLink extends AbstractElementProcessor {
+
+    private static String site;
+    private static String suffix;
+
+    public static void append(final Request request, final String description, final String helpReference) {
+        request.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 Request request) {
+        final String description = null;
+        final String helpReference = request.getRequiredProperty("ref");
+        append(request, description, helpReference);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/History.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/History.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/History.java
new file mode 100644
index 0000000..2f2a9b7
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/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;
+
+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.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;
+
+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 Request request) {
+        final String action = request.getOptionalProperty("action", "display");
+        final Crumbs crumbs = getCrumbs(request);
+        if (action.equals("display") && crumbs != null) {
+            write(crumbs, request);
+        } else if (action.equals("link")) {
+            final String name = request.getRequiredProperty(NAME);
+            final String link = request.getRequiredProperty(LINK_VIEW);
+            crumbs.add(name, link);
+        } else if (action.equals("object")) {
+            final String id = request.getOptionalProperty(OBJECT);
+            final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), id);
+            final String name = object.titleString();
+            String link = request.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 Request request) {
+        if (crumbs.isEmpty()) {
+            return;
+        }
+
+        request.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) {
+                request.appendHtml("<span class=\"separator\"> | </span>");
+            }
+            if (i == length - 1 || link == null) {
+                request.appendHtml("<span class=\"disabled\">");
+                request.appendHtml(crumb.name);
+                request.appendHtml("</span>");
+            } else {
+                request.appendHtml("<a class=\"linked\" href=\"" + link + "\">");
+                request.appendHtml(crumb.name);
+                request.appendHtml("</a>");
+            }
+            i++;
+        }
+        request.appendHtml("</div>");
+    }
+
+    private Crumbs getCrumbs(final Request request) {
+        final RequestContext context = request.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/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/HtmlSnippet.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/HtmlSnippet.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/HtmlSnippet.java
new file mode 100644
index 0000000..f1807df
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/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.view;
+
+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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/Snippet.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/Snippet.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/Snippet.java
new file mode 100644
index 0000000..b8a7b3e
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/Snippet.java
@@ -0,0 +1,27 @@
+/*
+ *  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;
+
+public interface Snippet {
+
+    String getHtml();
+
+    String errorAt();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/SwfTag.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/SwfTag.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/SwfTag.java
new file mode 100644
index 0000000..6b097bb
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/SwfTag.java
@@ -0,0 +1,90 @@
+/*
+ *  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;
+
+import org.apache.isis.viewer.scimpi.dispatcher.action.Attributes;
+
+public class SwfTag implements Snippet {
+
+    public static final int END = 0;
+    public static final int EMPTY = 1;
+    public static final int START = 2;
+    private final String tagName;
+    private final int type;
+    private final Attributes attributes;
+    private final String lineNumbers;
+    private final String path;
+
+    public SwfTag(final String tagName, final Attributes attributes, final int type, final String lineNumbers, final String path) {
+        this.tagName = tagName;
+        this.attributes = attributes;
+        this.type = type;
+        this.lineNumbers = lineNumbers;
+        this.path = path;
+    }
+
+    @Override
+    public String getHtml() {
+        return tagName;
+    }
+    
+    public String getPath() { 
+        return path; 
+    } 
+
+    public int getType() {
+        return type;
+    }
+
+    public String getName() {
+        return tagName;
+    }
+
+    public Attributes getAttributes() {
+        return attributes;
+    }
+
+    @Override
+    public String errorAt() {
+        return path + ":" + lineNumbers;
+    }
+
+    public String debug() {
+        return path + ":" + lineNumbers + " - " + getAttributes();
+    }
+
+    @Override
+    public String toString() {
+        String t = null;
+        switch (type) {
+        case EMPTY:
+            t = "empty";
+            break;
+        case START:
+            t = "start";
+            break;
+        case END:
+            t = "end";
+            break;
+        }
+        return "SwfTag[name=" + tagName + ",path=" + path + ",line=" + lineNumbers + ",type=" + t + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/VersionNumber.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/VersionNumber.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/VersionNumber.java
new file mode 100644
index 0000000..6b054b1
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/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;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.isis.viewer.scimpi.dispatcher.AbstractElementProcessor;
+import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+
+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 Request request) {
+        if (version == null) {
+            version = "0000"; // default revision number
+            loadRevisonNumber(request.getContext());
+        }
+        request.appendHtml(version);
+    }
+
+    private void loadRevisonNumber(final RequestContext 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/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionButton.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionButton.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionButton.java
new file mode 100644
index 0000000..740de00
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionButton.java
@@ -0,0 +1,237 @@
+/*
+ *  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.action;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+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.processor.Request;
+import org.apache.isis.viewer.scimpi.dispatcher.util.MethodsUtils;
+import org.apache.isis.viewer.scimpi.dispatcher.view.HelpLink;
+
+public class ActionButton extends AbstractElementProcessor {
+    private static final Logger LOG = LoggerFactory.getLogger(ActionButton.class);
+
+    // 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 static Where where = Where.ANYWHERE;
+
+    @Override
+    public void process(final Request request) {
+        final String objectId = request.getOptionalProperty(OBJECT);
+        final String methodName = request.getRequiredProperty(METHOD);
+        final String forwardResultTo = request.getOptionalProperty(VIEW);
+        final String forwardVoidTo = request.getOptionalProperty(VOID);
+        final String forwardErrorTo = request.getOptionalProperty(ERROR);
+        final String variable = request.getOptionalProperty(RESULT_NAME);
+        final String scope = request.getOptionalProperty(SCOPE);
+        final String buttonTitle = request.getOptionalProperty(BUTTON_TITLE);
+        String resultOverride = request.getOptionalProperty(RESULT_OVERRIDE);
+        final String idName = request.getOptionalProperty(ID, methodName);
+        final String className = request.getOptionalProperty(CLASS);
+        final boolean showMessage = request.isRequested(SHOW_MESSAGE, false);
+        final String completionMessage = request.getOptionalProperty(MESSAGE);
+
+        final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), objectId);
+        final String version = request.getContext().mapVersion(object);
+        final ObjectAction action = MethodsUtils.findAction(object, methodName);
+
+        final ActionContent parameterBlock = new ActionContent(action);
+        request.setBlockContent(parameterBlock);
+        request.processUtilCloseTag();
+        final String[] parameters = parameterBlock.getParameters();
+        final ObjectAdapter[] objectParameters;
+        
+        final ObjectAdapter target;
+        if (false /*action.isContributed()*/) {
+//            objectParameters= null;
+//            System.arraycopy(parameters, 0, parameters, 1, parameters.length - 1);
+//            parameters[0] = request.getContext().mapObject(object, Scope.REQUEST);
+//            target =  action.realTarget(object);
+//            if (!action.hasReturn() && resultOverride == null) {
+//                resultOverride = parameters[0];
+//            }
+        } else {
+            objectParameters = new ObjectAdapter[parameters.length];
+            target = object;
+            int i = 0;
+            for (final ObjectActionParameter spec : action.getParameters()) {
+                final ObjectSpecification type = spec.getSpecification();
+                if (parameters[i] == null) {
+                    objectParameters[i] = null;
+                } else if (type.getFacet(ParseableFacet.class) != null) {
+                    final ParseableFacet facet = type.getFacet(ParseableFacet.class);
+                    Localization localization = IsisContext.getLocalization(); 
+                    objectParameters[i] = facet.parseTextEntry(null, parameters[i], localization); 
+                } else {
+                    objectParameters[i] = MethodsUtils.findObject(request.getContext(), parameters[i]);
+                }
+                i++;
+            }
+        }
+
+        if (MethodsUtils.isVisibleAndUsable(object, action, where) && MethodsUtils.canRunMethod(object, action, objectParameters).isAllowed()) {
+            // TODO use the form creation mechanism as used in ActionForm
+            write(request, target, action, parameters, version, forwardResultTo, forwardVoidTo, forwardErrorTo, variable, scope, buttonTitle, completionMessage, resultOverride, idName, className);
+        }
+
+        if (showMessage) {
+            final Consent usable = action.isUsable(IsisContext.getAuthenticationSession(), object, where);
+            if (usable.isVetoed()) {
+                final String notUsable = usable.getReason();
+                if (notUsable != null) {
+                    String title = buttonTitle == null ? action.getName() : buttonTitle;
+                    disabledButton(request, title, notUsable, idName, className);
+                }
+            } else {
+                final Consent valid = action.isProposedArgumentSetValid(object, objectParameters);
+                final String notValid = valid.getReason();
+                if (notValid != null) {
+                    String title = buttonTitle == null ? action.getName() : buttonTitle;
+                    disabledButton(request, title, notValid, idName, className);
+                }
+            }
+        }
+
+        request.popBlockContent();
+    }
+
+    private void disabledButton(final Request request, final String buttonTitle, String message, String id, String className) {
+        if (className == null) {
+            className = "access";
+        }
+        request.appendHtml("<div id=\"" + id + "\" class=\"" + className + " disabled-form\">");
+        request.appendHtml("<div class=\"button disabled\" title=\"");
+        request.appendAsHtmlEncoded(message);
+        request.appendHtml("\" >" + buttonTitle);
+        request.appendHtml("</div>");
+        request.appendHtml("</div>");
+    }
+
+    public static void write(
+            final Request request,
+            final ObjectAdapter object,
+            final ObjectAction action,
+            final String[] parameters,
+            final String version,
+            String forwardResultTo,
+            String forwardVoidTo,
+            String forwardErrorTo,
+            final String variable,
+            final String scope,
+            String buttonTitle,
+            final String completionMessage,
+            final String resultOverride,
+            final String idName,
+            final String className) {
+        final RequestContext context = request.getContext();
+
+        buttonTitle = buttonTitle != null ? buttonTitle : action.getName();
+
+        if (action.isVisible(IsisContext.getAuthenticationSession(), object, where).isVetoed()) {
+            LOG.info("action not visible " + action.getName());
+            return;
+        }
+        final Consent usable = action.isUsable(IsisContext.getAuthenticationSession(), object, where);
+        if (usable.isVetoed()) {
+            LOG.info("action not available: " + usable.getReason());
+            return;
+        }
+
+        /*
+         * 
+         * TODO this mechanism fails as it tries to process tags - which we dont
+         * need! Also it calls action 'edit' (not 'action'). Field[] fields =
+         * new Field[0]; HiddenField[] hiddenFields = new HiddenField[] { new
+         * HiddenField("service", serviceId), new HiddenField("method",
+         * methodName), new HiddenField("view", forwardToView), variable == null
+         * ? null : new HiddenField("variable", variable), };
+         * Form.createForm(request, buttonTitle, fields, hiddenFields, false);
+         */
+
+        final String objectId = context.mapObject(object, Scope.INTERACTION);
+        final String idSegment = idName == null ? "" : ("id=\"" + idName + "\" ");
+        final String classSegment = "class=\"" + (className == null ? "action in-line" : className) + "\"";
+        request.appendHtml("\n<form " + idSegment + classSegment + " action=\"action.app\" method=\"post\">\n");
+        if (objectId == null) {
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + OBJECT + "\" value=\"" + context.getVariable(RequestContext.RESULT) + "\" />\n");
+        } else {
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + OBJECT + "\" value=\"" +  StringEscapeUtils.escapeHtml(objectId) + "\" />\n");
+        }
+        request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + VERSION + "\" value=\"" + version + "\" />\n");
+        if (scope != null) {
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + SCOPE + "\" value=\"" + scope + "\" />\n");
+        }
+        request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + METHOD + "\" value=\"" + action.getId() + "\" />\n");
+        if (forwardResultTo != null) {
+            forwardResultTo = context.fullFilePath(forwardResultTo);
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + VIEW + "\" value=\"" + forwardResultTo + "\" />\n");
+        }
+        if (forwardErrorTo == null) {
+            forwardErrorTo = request.getContext().getResourceFile();
+        }
+        forwardErrorTo = context.fullFilePath(forwardErrorTo);
+        request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + ERROR + "\" value=\"" + forwardErrorTo + "\" />\n");
+        if (forwardVoidTo == null) {
+            forwardVoidTo = request.getContext().getResourceFile();
+        }
+        forwardVoidTo = context.fullFilePath(forwardVoidTo);
+        request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + VOID + "\" value=\"" + forwardVoidTo + "\" />\n");
+        if (variable != null) {
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + RESULT_NAME + "\" value=\"" + variable + "\" />\n");
+        }
+        if (resultOverride != null) {
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + RESULT_OVERRIDE + "\" value=\"" + resultOverride + "\" />\n");
+        }
+        if (completionMessage != null) {
+            request.appendHtml("  <input type=\"hidden\" name=\"" + "_" + MESSAGE + "\" value=\"" + completionMessage + "\" />\n");
+        }
+
+        for (int i = 0; i < parameters.length; i++) {
+            request.appendHtml("  <input type=\"hidden\" name=\"param" + (i + 1) + "\" value=\"" + parameters[i] + "\" />\n");
+        }
+        request.appendHtml(request.getContext().interactionFields());
+        request.appendHtml("  <input class=\"button\" type=\"submit\" value=\"" + buttonTitle + "\" name=\"execute\" title=\"" + action.getDescription() + "\" />");
+        HelpLink.append(request, action.getDescription(), action.getHelp());
+        request.appendHtml("\n</form>\n");
+    }
+
+    @Override
+    public String getName() {
+        return "action-button";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/2c7cfbfe/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionContent.java
----------------------------------------------------------------------
diff --git a/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionContent.java b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionContent.java
new file mode 100644
index 0000000..2466726
--- /dev/null
+++ b/mothballed/component/viewer/scimpi/dispatcher/src/main/java/org/apache/isis/viewer/scimpi/dispatcher/view/action/ActionContent.java
@@ -0,0 +1,77 @@
+/*
+ *  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.action;
+
+import java.util.List;
+
+import org.apache.isis.applib.profiles.Localization;
+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.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.scimpi.dispatcher.BlockContent;
+import org.apache.isis.viewer.scimpi.dispatcher.ScimpiException;
+import org.apache.isis.viewer.scimpi.dispatcher.processor.Request;
+
+public class ActionContent implements BlockContent {
+    private final ObjectAction action;
+    private final String[] parameters;
+    private int next;
+
+    public ActionContent(final ObjectAction action) {
+        this.action = action;
+        this.parameters = new String[action.getParameterCount()];
+    }
+
+    public void setParameter(final String field, final String value) {
+        int index;
+        if (field == null) {
+            index = next++;
+        } else {
+            index = Integer.valueOf(field).intValue() - 1;
+        }
+        if (index < 0 || index >= parameters.length) {
+            throw new ScimpiException("Parameter numbers should be between 1 and " + parameters.length + ": " + index);
+        }
+        parameters[index] = value;
+    }
+
+    public ObjectAdapter[] getParameters(final Request request) {
+        final ObjectAdapter[] params = new ObjectAdapter[parameters.length];
+        final List<ObjectActionParameter> pars = action.getParameters();
+        for (int i = 0; i < parameters.length; i++) {
+            final ObjectSpecification typ = pars.get(i).getSpecification();
+            if (typ.getFacet(ParseableFacet.class) != null) {
+                final ParseableFacet facet = typ.getFacet(ParseableFacet.class);
+                Localization localization = IsisContext.getLocalization(); 
+                params[i] = facet.parseTextEntry(null, parameters[i], localization);            
+            } else {
+                params[i] = request.getContext().getMappedObject(parameters[i]);
+            }
+        }
+        return params;
+    }
+
+    public String[] getParameters() {
+        return parameters;
+    }
+}