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/09/03 14:32:19 UTC

[28/87] [abbrv] [partial] isis git commit: ISIS-1194: moving the wicket submodules to be direct children of core; removing the isis-viewer-wicket parent pom.

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/welcome/WelcomePanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/welcome/WelcomePanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/welcome/WelcomePanelFactory.java
new file mode 100644
index 0000000..14a4099
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/welcome/WelcomePanelFactory.java
@@ -0,0 +1,56 @@
+/*
+ *  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.wicket.ui.components.welcome;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.viewer.wicket.model.models.WelcomeModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+/**
+ * {@link ComponentFactory} for {@link WelcomePanel}.
+ */
+public class WelcomePanelFactory extends ComponentFactoryAbstract {
+
+    private static final long serialVersionUID = 1L;
+
+    // TODO update this message once Bootstrap is used for UI
+    private static final String DEFAULT_MESSAGE = "Apache Isis' Wicket Viewer combines the power of Apache Wicket " + "for web UIs with Apache Isis for domain modelling.  " + "Out-of-the box you get a fully-functional webapp just from " + "your domain objects; you can then customize the UI by "
+            + "writing custom Wicket components, replacing the page layouts or " + "simply by altering the CSS";
+
+
+    public WelcomePanelFactory() {
+        super(ComponentType.WELCOME, WelcomePanel.class);
+    }
+
+    @Override
+    public ApplicationAdvice appliesTo(final IModel<?> model) {
+        return ApplicationAdvice.APPLIES;
+    }
+
+    @Override
+    public Component createComponent(final String id, final IModel<?> model) {
+        return new WelcomePanel(id, new WelcomeModel(DEFAULT_MESSAGE));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java
new file mode 100644
index 0000000..66a781d
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java
@@ -0,0 +1,136 @@
+/**
+ *  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.wicket.ui.components.widgets;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.vaynberg.wicket.select2.TextChoiceProvider;
+import org.apache.wicket.Session;
+import org.apache.wicket.util.convert.IConverter;
+import org.apache.wicket.util.string.Strings;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.IsisConverterLocator;
+
+public abstract class ObjectAdapterMementoProviderAbstract extends TextChoiceProvider<ObjectAdapterMemento> {
+
+    private static final long serialVersionUID = 1L;
+    
+    protected static final String NULL_PLACEHOLDER = "$$_isis_null_$$";
+    private static final String NULL_DISPLAY_TEXT = "";
+
+    private final ScalarModel scalarModel;
+    private final WicketViewerSettings wicketViewerSettings;
+
+    public ObjectAdapterMementoProviderAbstract(final ScalarModel scalarModel, final WicketViewerSettings wicketViewerSettings) {
+        this.scalarModel = scalarModel;
+        this.wicketViewerSettings = wicketViewerSettings;
+    }
+    
+    @Override
+    protected String getDisplayText(final ObjectAdapterMemento choice) {
+        if (choice == null) {
+            return NULL_DISPLAY_TEXT;
+        }
+
+        final ObjectAdapter objectAdapter = choice.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+        final IConverter<Object> converter = findConverter(objectAdapter);
+        return converter != null
+                ? converter.convertToString(objectAdapter.getObject(), getLocale())
+                : objectAdapter.titleString(null);
+    }
+
+    protected Locale getLocale() {
+        return Session.exists() ? Session.get().getLocale() : Locale.ENGLISH;
+    }
+
+    protected IConverter<Object> findConverter(final ObjectAdapter objectAdapter) {
+        return IsisConverterLocator.findConverter(objectAdapter, wicketViewerSettings);
+    }
+
+    @Override
+    protected Object getId(final ObjectAdapterMemento choice) {
+        return choice != null? choice.asString(): NULL_PLACEHOLDER;
+    }
+
+    @Override
+    public void query(final String term, final int page, final com.vaynberg.wicket.select2.Response<ObjectAdapterMemento> response) {
+        
+        final List<ObjectAdapterMemento> mementos = Lists.newArrayList(obtainMementos(term));
+        // if not mandatory, and the list doesn't contain null already, then add it in.
+        if(!scalarModel.isRequired() && !mementos.contains(null)) {
+            mementos.add(0, null);
+        }
+        response.addAll(mementos);
+    }
+
+    protected abstract List<ObjectAdapterMemento> obtainMementos(String term);
+
+    /**
+     * Filters all choices against a term by using their
+     * {@link org.apache.isis.core.metamodel.adapter.ObjectAdapter#titleString(org.apache.isis.core.metamodel.adapter.ObjectAdapter) title string}
+     *
+     * @param term The term entered by the user
+     * @param choicesMementos The collections of choices to filter
+     * @return A list of all matching choices
+     */
+    protected List<ObjectAdapterMemento> obtainMementos(String term, Collection<ObjectAdapterMemento> choicesMementos) {
+        List<ObjectAdapterMemento> matches = Lists.newArrayList();
+        if (Strings.isEmpty(term)) {
+            matches.addAll(choicesMementos);
+        } else {
+            for (ObjectAdapterMemento candidate : choicesMementos) {
+                ObjectAdapter objectAdapter = candidate.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+                String title = objectAdapter.titleString(objectAdapter);
+                if (title.toLowerCase().contains(term.toLowerCase())) {
+                    matches.add(candidate);
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    @Override
+    public Collection<ObjectAdapterMemento> toChoices(final Collection<String> ids) {
+        final Function<String, ObjectAdapterMemento> function = new Function<String, ObjectAdapterMemento>() {
+
+            @Override
+            public ObjectAdapterMemento apply(final String input) {
+                if(NULL_PLACEHOLDER.equals(input)) {
+                    return null;
+                }
+                final RootOid oid = RootOidDefault.deString(input, ObjectAdapterMemento.getOidMarshaller());
+                return ObjectAdapterMemento.createPersistent(oid);
+            }
+        };
+        return Collections2.transform(ids, function);
+    }
+    
+    protected ScalarModel getScalarModel() {
+        return scalarModel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/FormGroup.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/FormGroup.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/FormGroup.java
new file mode 100644
index 0000000..0da3a5d
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/FormGroup.java
@@ -0,0 +1,71 @@
+/*
+ *  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.wicket.ui.components.widgets.bootstrap;
+
+import de.agilecoders.wicket.core.util.Attributes;
+
+import org.apache.wicket.feedback.FeedbackMessage;
+import org.apache.wicket.feedback.FeedbackMessages;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * A container around Bootstrap form component that sets
+ * <a href="http://getbootstrap.com/css/#forms-control-validation">validation state</a>
+ */
+public class FormGroup extends WebMarkupContainer {
+
+    private final FormComponent<?> formComponent;
+
+    /**
+     * Constructor
+     *
+     * @param id The component id
+     * @param formComponent The form component that controls the validation state of the form group
+     */
+    public FormGroup(String id, FormComponent<?> formComponent) {
+        super(id);
+
+        this.formComponent = Args.notNull(formComponent, "formComponent");
+    }
+
+    @Override
+    protected void onComponentTag(ComponentTag tag) {
+        super.onComponentTag(tag);
+
+        Attributes.addClass(tag, "form-group");
+
+        applyFeedbackClasses(tag, formComponent);
+    }
+
+    protected void applyFeedbackClasses(ComponentTag tag, FormComponent<?> formComponent) {
+        FeedbackMessages feedbackMessages = formComponent.getFeedbackMessages();
+        for (FeedbackMessage feedbackMessage : feedbackMessages) {
+            if (feedbackMessage.getLevel() == FeedbackMessage.ERROR) {
+                Attributes.addClass(tag, "has-error");
+            } else if (feedbackMessage.getLevel() == FeedbackMessage.WARNING) {
+                Attributes.addClass(tag, "has-warning");
+            } else if (feedbackMessage.getLevel() == FeedbackMessage.SUCCESS) {
+                Attributes.addClass(tag, "has-success");
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/ModalDialog.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/ModalDialog.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/ModalDialog.java
new file mode 100644
index 0000000..1fe06f6
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/bootstrap/ModalDialog.java
@@ -0,0 +1,93 @@
+/**
+ *  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.wicket.ui.components.widgets.bootstrap;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.Draggable;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.DraggableConfig;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
+
+/**
+ * A base class for all modal dialogs
+ */
+public class ModalDialog<T> extends Modal<T> implements ActionPrompt {
+
+    public ModalDialog(String markupId) {
+        this(markupId, null);
+    }
+
+    public ModalDialog(String id, IModel<T> model) {
+        super(id, model);
+
+        setFadeIn(false);
+        setUseKeyboard(true);
+        setDisableEnforceFocus(true);
+        setOutputMarkupPlaceholderTag(true);
+        WebMarkupContainer emptyComponent = new WebMarkupContainer(getContentId());
+        add(emptyComponent);
+    }
+
+    @Override
+    public void setTitle(Component component, AjaxRequestTarget target) {
+        ((MarkupContainer)get("dialog:header")).addOrReplace(component);
+    }
+
+    @Override
+    public void setPanel(Component component, AjaxRequestTarget target) {
+        addOrReplace(component);
+    }
+
+    @Override
+    public void showPrompt(AjaxRequestTarget target) {
+        setVisible(true);
+        target.add(this);
+        show(target);
+    }
+
+    @Override
+    public String getTitleId() {
+        return "header-label";
+    }
+
+    @Override
+    public String getContentId() {
+        return "content";
+    }
+
+    @Override
+    public void closePrompt(AjaxRequestTarget target) {
+        if (target != null) {
+            close(target);
+        }
+        setVisible(false);
+    }
+
+    @Override
+    protected WebMarkupContainer createDialog(String id) {
+        WebMarkupContainer dialog = super.createDialog(id);
+        dialog.add(AttributeAppender.append("class", "modal-dialog-center"));
+        dialog.add(new Draggable(new DraggableConfig().withHandle(".modal-header").withCursor("move")));
+        return dialog;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModel.java
new file mode 100644
index 0000000..02b1ce3
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModel.java
@@ -0,0 +1,126 @@
+/**
+ *  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.wicket.ui.components.widgets.breadcrumbs;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+
+public class BreadcrumbModel implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    
+    private static final int MAX_SIZE = 5;
+
+    private final Map<String, EntityModel> entityModelByOidStr = Maps.newHashMap();
+    private final Map<EntityModel, String> titleByEntityModel = Maps.newHashMap();
+    private final Map<EntityModel, String> oidStrByEntityModel = Maps.newHashMap();
+    private final List<EntityModel> list = Lists.newArrayList();
+    
+    public List<EntityModel> getList() {
+        return Collections.unmodifiableList(list);
+    }
+
+    public void visited(final EntityModel entityModel) {
+
+        // ignore view models
+        if(entityModel.getTypeOfSpecification().isViewModel()) {
+            return;
+        }
+
+        final String oidStr = oidStrFor(entityModel);
+        
+        removeExisting(oidStr);
+        addToStart(oidStr, entityModel);
+        
+        trimTo(MAX_SIZE);
+    }
+
+    private String oidStrFor(final EntityModel entityModel) {
+        final PageParameters pageParameters = entityModel.getPageParametersWithoutUiHints();
+        return PageParameterNames.OBJECT_OID.getStringFrom(pageParameters);
+    }
+
+    private void addToStart(final String oidStr, final EntityModel entityModel) {
+        entityModelByOidStr.put(oidStr, entityModel);
+        titleByEntityModel.put(entityModel, entityModel.getTitle());
+        oidStrByEntityModel.put(entityModel, oidStr);
+        list.add(0, entityModel);
+    }
+
+    private void removeExisting(final String oidStr) {
+        final EntityModel existingModel = entityModelByOidStr.get(oidStr);
+        if(existingModel != null) {
+            remove(oidStr, existingModel);
+        }
+    }
+
+    private void trimTo(final int size) {
+        if(list.size() <= size) {
+            return;
+        } 
+        final List<EntityModel> modelsToRemove = list.subList(size, list.size());
+        for (final EntityModel model : modelsToRemove) {
+            final String oidStr = oidStrByEntityModel.get(model);
+            remove(oidStr, model);
+        }
+    }
+
+    private void remove(final String oidStr, final EntityModel model) {
+        entityModelByOidStr.remove(oidStr);
+        titleByEntityModel.remove(model);
+        oidStrByEntityModel.remove(model);
+        list.remove(model);
+    }
+
+    public void remove(String oidStr) {
+        EntityModel removedModel = entityModelByOidStr.remove(oidStr);
+        if(removedModel != null) {
+            remove(removedModel);
+        }
+    }
+
+    public void remove(EntityModel entityModel) {
+        String oidStr = oidStrByEntityModel.get(entityModel);
+        if(oidStr != null) {
+            remove(oidStr, entityModel);
+        }
+    }
+
+    public String titleFor(final EntityModel model) {
+        return titleByEntityModel.get(model);
+    }
+
+    public EntityModel lookup(String oidStr) {
+        if(oidStr == null) {
+            return null;
+        }
+        return entityModelByOidStr.get(oidStr);
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModelProvider.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModelProvider.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModelProvider.java
new file mode 100644
index 0000000..1f41ce2
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbModelProvider.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.wicket.ui.components.widgets.breadcrumbs;
+
+
+public interface BreadcrumbModelProvider {
+
+    BreadcrumbModel getBreadcrumbModel();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.html
new file mode 100644
index 0000000..13d7bdd
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+    <body>
+        <wicket:panel>
+            <span class="breadcrumbPanel">
+                <input wicket:id="breadcrumbs" type="hidden" class="autoComplete form-control select2-remote" style="width: 100%" />
+            </span>
+        </wicket:panel>
+    </body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.java
new file mode 100644
index 0000000..76badf0
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/breadcrumbs/BreadcrumbPanel.java
@@ -0,0 +1,115 @@
+/**
+ *  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.wicket.ui.components.widgets.breadcrumbs;
+
+import java.util.Collection;
+import com.vaynberg.wicket.select2.Response;
+import com.vaynberg.wicket.select2.Select2Choice;
+import com.vaynberg.wicket.select2.Settings;
+import com.vaynberg.wicket.select2.TextChoiceProvider;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.isis.core.commons.authentication.MessageBroker;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.ui.errors.JGrowlUtil;
+import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+public class BreadcrumbPanel extends PanelAbstract<IModel<Void>> {
+
+    private static final long serialVersionUID = 1L;
+    
+    private static final String ID_BREADCRUMBS = "breadcrumbs";
+
+    public BreadcrumbPanel(String id) {
+        super(id);
+    }
+    
+    @Override
+    protected void onInitialize() {
+        super.onInitialize();
+        
+        final BreadcrumbModelProvider session = (BreadcrumbModelProvider) getSession();
+        final BreadcrumbModel breadcrumbModel = session.getBreadcrumbModel();
+        
+        final IModel<EntityModel> entityModel = new Model<EntityModel>();
+        final Select2Choice<EntityModel> breadcrumbChoice = new Select2Choice<EntityModel>(ID_BREADCRUMBS, entityModel);
+
+        breadcrumbChoice.add(
+            new AjaxFormComponentUpdatingBehavior("change"){
+    
+                private static final long serialVersionUID = 1L;
+    
+                @Override
+                protected void onUpdate(AjaxRequestTarget target) {
+                    final String oidStr = breadcrumbChoice.getInput();
+                    final EntityModel selectedModel = breadcrumbModel.lookup(oidStr);
+                    if(selectedModel == null) {
+                        final MessageBroker messageBroker = IsisContext.getAuthenticationSession().getMessageBroker();
+                        messageBroker.addWarning("Cannot find object");
+                        String feedbackMsg = JGrowlUtil.asJGrowlCalls(messageBroker);
+                        target.appendJavaScript(feedbackMsg);
+                        breadcrumbModel.remove(oidStr);
+                        return;
+                    }
+                    setResponsePage(EntityPage.class, selectedModel.getPageParameters());
+                }
+            });
+        
+        final Settings settings = breadcrumbChoice.getSettings();
+        settings.setMinimumInputLength(0);
+        settings.setWidth("100%");
+        
+        breadcrumbChoice.setProvider(new TextChoiceProvider<EntityModel>() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected String getDisplayText(EntityModel choice) {
+                return breadcrumbModel.titleFor(choice);
+            }
+
+            @Override
+            protected Object getId(EntityModel choice) {
+                try {
+                    return PageParameterNames.OBJECT_OID.getStringFrom(choice.getPageParameters());
+                } catch(Exception ex) {
+                    breadcrumbModel.remove(choice);
+                    return null;
+                }
+            }
+
+            @Override
+            public void query(String term, int page, Response<EntityModel> response) {
+                response.addAll(breadcrumbModel.getList());
+            }
+
+            @Override
+            public Collection<EntityModel> toChoices(Collection<String> ids) {
+                return breadcrumbModel.getList();
+            }
+            
+        });
+        addOrReplace(breadcrumbChoice);
+    }
+
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.html
new file mode 100644
index 0000000..2eb63ca
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<html>
+	<body>
+		<wicket:panel>
+			<span wicket:id="container" class="containedButtonPanel">
+				<form wicket:id="form">
+					<input type="submit" wicket:id="button" />
+				</form>
+			</span>
+		</wicket:panel>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
new file mode 100644
index 0000000..5319a87
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
@@ -0,0 +1,92 @@
+/*
+ *  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.wicket.ui.components.widgets.buttons;
+
+import java.util.List;
+import com.google.common.collect.Lists;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+/**
+ * A button contained within its own form.
+ */
+public class ContainedButtonPanel extends PanelAbstract<Model<String>> {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_CONTAINER = "container";
+    private static final String ID_FORM = "form";
+    private static final String ID_BUTTON = "button";
+
+    private final Button button;
+    private final List<Component> componentsToRerender = Lists.newArrayList();
+
+    public ContainedButtonPanel(final String id, final String caption) {
+        super(id, Model.of(caption));
+
+        final WebMarkupContainer markupContainer = new WebMarkupContainer(ID_CONTAINER);
+        add(markupContainer);
+        final Form<Object> form = new Form<Object>(ID_FORM);
+        markupContainer.add(form);
+        button = new AjaxButton(ID_BUTTON, getModel()) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                setDefaultFormProcessing(false);
+                ContainedButtonPanel.this.onSubmit();
+                if (target != null) {
+                    for (final Component component : componentsToRerender) {
+                        //target.addComponent(component);
+                        target.add(component);
+                    }
+                }
+            }
+        };
+        form.add(button);
+    }
+
+    public void addComponentToRerender(final Component component) {
+        component.setOutputMarkupPlaceholderTag(true);
+        componentsToRerender.add(component);
+    }
+
+    public void setCaption(final String string) {
+        button.setModelValue(new String[] { string });
+    }
+
+    public void setLabel(final Model<String> labelModel) {
+        button.setLabel(labelModel);
+    }
+
+    /**
+     * Hook method for (typically anonymous) subclasses to override.
+     */
+    public void onSubmit() {
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.html
new file mode 100644
index 0000000..1bb1346
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<html>
+	<body>
+		<wicket:panel>
+			<span class="toggleButtonsPanel">
+	    		<span wicket:id="button1"/>
+	    		<span wicket:id="button2"/>
+			</span>
+		</wicket:panel>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.java
new file mode 100644
index 0000000..8faff9a
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ToggleButtonsPanel.java
@@ -0,0 +1,148 @@
+/*
+ *  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.wicket.ui.components.widgets.buttons;
+
+import java.io.Serializable;
+import org.apache.wicket.Component;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+/**
+ * Abstraction of show/hide, ie two buttons only one of which is visible.
+ */
+public class ToggleButtonsPanel extends PanelAbstract<EntityModel> {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_BUTTON_1 = "button1";
+    private static final String ID_BUTTON_2 = "button2";
+
+    private boolean flag;
+    private Toggler toggler;
+
+    private ContainedButtonPanel button1;
+
+    private ContainedButtonPanel button2;
+
+    public ToggleButtonsPanel(final String id, final String button1Caption, final String button2Caption) {
+        super(id, null);
+        this.flag = false;
+        buildGui(button1Caption, button2Caption);
+        onInit();
+    }
+
+    private void buildGui(final String button1Caption, final String button2Caption) {
+        button1 = new ContainedButtonPanel(ID_BUTTON_1, button1Caption) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public void onSubmit() {
+                toggler.toggle();
+            }
+        };
+        addOrReplace(button1);
+
+        button2 = new ContainedButtonPanel(ID_BUTTON_2, button2Caption) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public void onSubmit() {
+                toggler.toggle();
+            }
+        };
+        toggler = new Toggler(button1, button2);
+        addOrReplace(button2);
+    }
+
+    public void addComponentToRerender(final Component... components) {
+        for (final Component component : components) {
+            button1.addComponentToRerender(component);
+            button2.addComponentToRerender(component);
+        }
+    }
+
+    /**
+     * Hook method to override.
+     */
+    protected void onInit() {
+    }
+
+    /**
+     * Hook method to override.
+     */
+    protected void onButton1() {
+    }
+
+    /**
+     * Hook method to override.
+     */
+    protected void onButton2() {
+    }
+
+    /**
+     * For subclasses to use.
+     */
+    protected final void hideButton1() {
+        flag = true;
+        toggler.syncButtonVisibility();
+    }
+
+    /**
+     * For subclasses to use.
+     */
+    protected final void hideButton2() {
+        flag = false;
+        toggler.syncButtonVisibility();
+    }
+
+    private class Toggler implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final Component component1;
+        private final Component component2;
+
+        public Toggler(final Component component1, final Component component2) {
+            this.component1 = component1;
+            this.component2 = component2;
+            syncButtonVisibility();
+        }
+
+        public void toggle() {
+            fireHooks();
+            syncButtonVisibility();
+        }
+
+        private void fireHooks() {
+            flag = !flag;
+            if (flag) {
+                onButton1();
+            } else {
+                onButton2();
+            }
+        }
+
+        private void syncButtonVisibility() {
+            component1.setVisible(!flag);
+            component2.setVisible(flag);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.html
new file mode 100644
index 0000000..3491ab6
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<html>
+	<body>
+		<wicket:panel>
+			<span wicket:id="container" class="containedToggleboxPanel">
+				<form wicket:id="form" class="containedToggleboxPanelForm">
+					<input type="checkbox" wicket:id="togglebox" />
+				</form>
+			</span>
+		</wicket:panel>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java
new file mode 100644
index 0000000..af2ea6c
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java
@@ -0,0 +1,83 @@
+/*
+ *  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.wicket.ui.components.widgets.checkbox;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+/**
+ * A button contained within its own form.
+ */
+public class ContainedToggleboxPanel extends PanelAbstract<Model<Boolean>> {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_CONTAINER = "container";
+    private static final String ID_FORM = "form";
+    private static final String ID_TOGGLEBOX = "togglebox";
+
+    private final AjaxCheckBox checkbox;
+//    private final List<Component> componentsToRerender = Lists.newArrayList();
+
+    public ContainedToggleboxPanel(final String id) {
+        super(id);
+
+        final WebMarkupContainer markupContainer = new WebMarkupContainer(ID_CONTAINER);
+        add(markupContainer);
+        final Form<Object> form = new Form<Object>(ID_FORM);
+        markupContainer.add(form);
+        
+        checkbox = new AjaxCheckBox(ID_TOGGLEBOX, Model.of(false)) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected void onUpdate(AjaxRequestTarget target) {
+                ContainedToggleboxPanel.this.onSubmit(target);
+            }
+        };
+        form.add(checkbox);
+    }
+
+
+//    public void addComponentToRerender(final Component component) {
+//        component.setOutputMarkupPlaceholderTag(true);
+//        componentsToRerender.add(component);
+//    }
+
+    /**
+     * Hook method for (typically anonymous) subclasses to override.
+     */
+    public void onSubmit(AjaxRequestTarget target) {
+    }
+
+    /**
+     * Programmatic toggling. 
+     * @param target 
+     */
+    public void toggle(AjaxRequestTarget target) {
+        checkbox.setModelObject(!checkbox.getModelObject());
+        onSubmit(target);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/containers/UiHintPathSignificantWebMarkupContainer.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/containers/UiHintPathSignificantWebMarkupContainer.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/containers/UiHintPathSignificantWebMarkupContainer.java
new file mode 100644
index 0000000..d43033f
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/containers/UiHintPathSignificantWebMarkupContainer.java
@@ -0,0 +1,34 @@
+/**
+ *  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.wicket.ui.components.widgets.containers;
+
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.viewer.wicket.model.hints.UiHintPathSignificant;
+
+public class UiHintPathSignificantWebMarkupContainer extends WebMarkupContainer implements UiHintPathSignificant {
+    private static final long serialVersionUID = 1L;
+
+    public UiHintPathSignificantWebMarkupContainer(String id, IModel<?> model) {
+        super(id, model);
+    }
+
+    public UiHintPathSignificantWebMarkupContainer(String id) {
+        super(id);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css
new file mode 100644
index 0000000..ca08a38
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css
@@ -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.
+ */
+div.entitySimpleLinkPanel  {
+	display: inline
+}
+
+div.entitySimpleLinkPanel > div {
+	margin-left: 2px;
+}
+
+.entitySimpleLinkPanel .entityImage {
+	width: 16px;
+	height: 16px;
+}
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html
new file mode 100644
index 0000000..047b75d
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"  
+      xml:lang="en"  
+      lang="en">
+	<wicket:head>
+		<wicket:link>
+			<link href="EntityLinkSimplePanel.css" rel="stylesheet" type="text/css"/>
+		</wicket:link>
+	</wicket:head>
+	<body>
+		<wicket:panel>
+			<div class="entityLinkSimplePanel entityLinkComponentType">
+				<div>
+					<div wicket:id="entityIconAndTitle">[icon and title]</div>
+					<span wicket:id="entityTitleNull">(none)</span>
+				    <div class="clearfix"></div>
+	  			</div>
+			</div>
+		</wicket:panel>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java
new file mode 100644
index 0000000..cf04df6
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java
@@ -0,0 +1,97 @@
+/*
+ *  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.wicket.ui.components.widgets.entitysimplelink;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.CancelHintRequired;
+import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormComponentPanelAbstract;
+
+/**
+ * {@link FormComponentPanel} representing a reference to an entity: a link and
+ * (optionally) an autocomplete field.
+ */
+public class EntityLinkSimplePanel extends FormComponentPanelAbstract<ObjectAdapter> implements CancelHintRequired  {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_ENTITY_ICON_AND_TITLE = "entityIconAndTitle";
+    private static final String ID_ENTITY_TITLE_NULL = "entityTitleNull";
+    
+    public EntityLinkSimplePanel(final String id, final EntityModel entityModel) {
+        super(id, entityModel);
+        setType(ObjectAdapter.class);
+        buildGui();
+    }
+
+    public EntityModel getEntityModel() {
+        return (EntityModel) getModel();
+    }
+
+    private void buildGui() {
+        syncWithInput();
+    }
+
+    @Override
+    protected void onBeforeRender() {
+        syncWithInput();
+        super.onBeforeRender();
+    }
+
+    private void syncWithInput() {
+        final ObjectAdapter adapter = getPendingElseCurrentAdapter();
+
+        if (adapter != null) {
+            final EntityModel entityModelForLink = new EntityModel(adapter);
+            entityModelForLink.setContextAdapterIfAny(getEntityModel().getContextAdapterIfAny());
+            entityModelForLink.setRenderingHint(getEntityModel().getRenderingHint());
+            
+            final ComponentFactory componentFactory = getComponentFactoryRegistry().findComponentFactory(ComponentType.ENTITY_ICON_AND_TITLE, entityModelForLink);
+            final Component component = componentFactory.createComponent(entityModelForLink);
+            addOrReplace(component);
+            
+            permanentlyHide(ID_ENTITY_TITLE_NULL);
+        } else {
+            // represent no object by a simple label displaying '(none)'
+            addOrReplace(new Label(ID_ENTITY_TITLE_NULL, "(none)"));
+            permanentlyHide(ID_ENTITY_ICON_AND_TITLE);
+        }
+    }
+
+    @Override
+    public void onCancel() {
+    }
+
+    @Override
+    public void validate() {
+        // no-op since immutable
+    }
+    
+    private ObjectAdapter getPendingElseCurrentAdapter() {
+        return getEntityModel().getPendingElseCurrentAdapter();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java
new file mode 100644
index 0000000..f7c731d
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java
@@ -0,0 +1,54 @@
+/*
+ *  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.wicket.ui.components.widgets.entitysimplelink;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+public class EntityLinkSimplePanelFactory extends ComponentFactoryAbstract {
+
+    private static final long serialVersionUID = 1L;
+
+    public EntityLinkSimplePanelFactory() {
+        super(ComponentType.ENTITY_LINK, EntityLinkSimplePanel.class);
+    }
+
+    @Override
+    public ApplicationAdvice appliesTo(final IModel<?> model) {
+        if (!(model instanceof EntityModel)) {
+            return ApplicationAdvice.DOES_NOT_APPLY;
+        }
+        final EntityModel entityModel = (EntityModel) model;
+        final ObjectSpecification specification = entityModel.getTypeOfSpecification();
+        return appliesIf(specification != null && !specification.containsFacet(ValueFacet.class));
+    }
+
+    @Override
+    public Component createComponent(final String id, final IModel<?> model) {
+        final EntityModel scalarModel = (EntityModel) model;
+        return new EntityLinkSimplePanel(id, scalarModel);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/favicon/Favicon.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/favicon/Favicon.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/favicon/Favicon.java
new file mode 100644
index 0000000..f566271
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/favicon/Favicon.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.wicket.ui.components.widgets.favicon;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebComponent;
+import org.apache.wicket.util.string.Strings;
+
+/**
+ * A component for application favorite icon
+ */
+public class Favicon extends WebComponent {
+
+    @Inject(optional = true)
+    @Named("faviconUrl")
+    private String url;
+
+    @Inject(optional = true)
+    @Named("faviconContentType")
+    private String contentType;
+
+    public Favicon(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void onConfigure() {
+        super.onConfigure();
+
+        setVisible(!Strings.isEmpty(url));
+    }
+
+    @Override
+    protected void onComponentTag(ComponentTag tag) {
+        super.onComponentTag(tag);
+
+        tag.put("href", url);
+
+        if (!Strings.isEmpty(contentType)) {
+            tag.put("type", contentType);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/CancelHintRequired.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/CancelHintRequired.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/CancelHintRequired.java
new file mode 100644
index 0000000..5d060b2
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/CancelHintRequired.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.wicket.ui.components.widgets.formcomponent;
+
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.FormComponent;
+
+/**
+ * {@link FormComponent}s that require explicit notification that their owning
+ * {@link Form} has been cancelled should implement this interface.
+ */
+public interface CancelHintRequired {
+
+    void onCancel();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormComponentPanelAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormComponentPanelAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormComponentPanelAbstract.java
new file mode 100644
index 0000000..59f152e
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormComponentPanelAbstract.java
@@ -0,0 +1,166 @@
+/*
+ *  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.wicket.ui.components.widgets.formcomponent;
+
+import java.util.List;
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Session;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.model.IModel;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
+import org.apache.isis.viewer.wicket.model.isis.PersistenceSessionProvider;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
+import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistryAccessor;
+import org.apache.isis.viewer.wicket.ui.util.Components;
+
+/**
+ * Convenience adapter for {@link FormComponent}s that are implemented using the
+ * Wicket {@link FormComponentPanel}, providing the ability to build up the
+ * panel using other {@link ComponentType}s.
+ */
+public abstract class FormComponentPanelAbstract<T> extends FormComponentPanel<T> implements PersistenceSessionProvider, AuthenticationSessionProvider {
+
+    private static final long serialVersionUID = 1L;
+
+    private ComponentType componentType;
+
+    public FormComponentPanelAbstract(final String id, final IModel<T> model) {
+        super(id, model);
+        this.componentType = ComponentType.lookup(id);
+    }
+
+    public ComponentType getComponentType() {
+        return componentType;
+    }
+
+    /**
+     * For subclasses
+     * 
+     * @return
+     */
+    protected Component addOrReplace(final ComponentType componentType, final IModel<?> model) {
+        return getComponentFactoryRegistry().addOrReplaceComponent(this, componentType, model);
+    }
+
+    /**
+     * For subclasses
+     */
+    protected void permanentlyHide(final ComponentType... componentIds) {
+        permanentlyHide(this, componentIds);
+    }
+
+    /**
+     * For subclasses
+     */
+    public void permanentlyHide(final String... ids) {
+        permanentlyHide(this, ids);
+    }
+
+    /**
+     * For subclasses
+     */
+    protected void permanentlyHide(final MarkupContainer container, final ComponentType... componentIds) {
+        Components.permanentlyHide(container, componentIds);
+    }
+
+    /**
+     * For subclasses
+     */
+    public void permanentlyHide(final MarkupContainer container, final String... ids) {
+        Components.permanentlyHide(container, ids);
+    }
+
+    
+    // ///////////////////////////////////////////////////////////////////
+    // Hint support
+    // ///////////////////////////////////////////////////////////////////
+
+    public UiHintContainer getHintContainer() {
+        return hintContainerOf(this);
+    }
+
+    private UiHintContainer hintContainerOf(Component component) {
+        if(component == null) {
+            return null;
+        }
+        IModel<?> model = component.getDefaultModel();
+        if(model instanceof UiHintContainer) {
+            return (UiHintContainer) model;
+        }
+        // otherwise, go up the UI component hierarchy
+        return hintContainerOf(getParent()); 
+    }
+
+    // ///////////////////////////////////////////////////////////////////
+    // Convenience
+    // ///////////////////////////////////////////////////////////////////
+
+    protected ComponentFactoryRegistry getComponentFactoryRegistry() {
+        final ComponentFactoryRegistryAccessor cfra = (ComponentFactoryRegistryAccessor) getApplication();
+        return cfra.getComponentFactoryRegistry();
+    }
+
+    /**
+     * The underlying {@link AuthenticationSession Isis session} wrapped in the
+     * {@link #getWebSession() Wicket session}.
+     * 
+     * @return
+     */
+    @Override
+    public AuthenticationSession getAuthenticationSession() {
+        return ((AuthenticationSessionProvider) Session.get()).getAuthenticationSession();
+    }
+
+    // ///////////////////////////////////////////////////////////////////
+    // Dependencies (from IsisContext)
+    // ///////////////////////////////////////////////////////////////////
+
+    @Override
+    public PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+    protected List<ObjectAdapter> getServices() {
+        return getPersistenceSession().getServices();
+    }
+
+
+    // /////////////////////////////////////////////////
+    // *Provider impl.
+    // /////////////////////////////////////////////////
+    
+    @Override
+    public void injectInto(final Object candidate) {
+        if (AuthenticationSessionProviderAware.class.isAssignableFrom(candidate.getClass())) {
+            final AuthenticationSessionProviderAware cast = AuthenticationSessionProviderAware.class.cast(candidate);
+            cast.setAuthenticationSessionProvider(this);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormFeedbackPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormFeedbackPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormFeedbackPanel.java
new file mode 100644
index 0000000..d3ff54a
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/formcomponent/FormFeedbackPanel.java
@@ -0,0 +1,48 @@
+/*
+ *  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.wicket.ui.components.widgets.formcomponent;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+
+import org.apache.wicket.feedback.FeedbackMessage;
+import org.apache.wicket.feedback.IFeedbackMessageFilter;
+import org.apache.wicket.markup.html.form.FormComponent;
+
+/**
+ * {@link NotificationPanel} designed for forms; filters out any
+ * {@link FeedbackMessage}s from {@link FormComponent}s (the idea being that
+ * they will have their own {@link NotificationPanel}s.
+ */
+public class FormFeedbackPanel extends NotificationPanel {
+    private static final long serialVersionUID = 1L;
+
+    public FormFeedbackPanel(final String id) {
+        super(id);
+        setFilter(new IFeedbackMessageFilter() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public boolean accept(final FeedbackMessage message) {
+                return !(message.getReporter() instanceof FormComponent<?>);
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactory.java
new file mode 100644
index 0000000..6c07221
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactory.java
@@ -0,0 +1,33 @@
+/*
+ *  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.wicket.ui.components.widgets.linkandlabel;
+
+import java.io.Serializable;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+
+public interface ActionLinkFactory extends Serializable {
+
+    LinkAndLabel newLink(
+            final ObjectAdapterMemento adapter,
+            final ObjectAction noAction,
+            final String linkId);
+}