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 2014/10/22 08:52:32 UTC

git commit: ISIS-930: support for font awesome icons on (most) action buttons. Includes @CssClassFa and also support in the .layout.json file.

Repository: isis
Updated Branches:
  refs/heads/master 087ab15f6 -> 673a514e2


ISIS-930: support for font awesome icons on (most) action buttons.  Includes @CssClassFa and also support in the .layout.json file.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/673a514e
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/673a514e
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/673a514e

Branch: refs/heads/master
Commit: 673a514e23e3cabd779c52656a32f1e5f488d167
Parents: 087ab15
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Oct 22 07:52:13 2014 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Oct 22 07:52:13 2014 +0100

----------------------------------------------------------------------
 .../viewer/wicket/model/links/LinkAndLabel.java | 16 ++++-
 .../additionallinks/AdditionalLinksPanel.css    |  3 +
 .../additionallinks/AdditionalLinksPanel.html   |  3 +-
 .../additionallinks/AdditionalLinksPanel.java   | 12 ++++
 .../ajaxtable/BulkActionsLinkFactory.java       |  3 +-
 .../cssmenu/ActionLinkFactoryAbstract.java      |  6 +-
 .../widgets/cssmenu/ApplicationActionsPanel.css | 18 +++++
 .../cssmenu/ApplicationActionsPanel.html        |  3 +-
 .../cssmenu/ApplicationActionsPanel.java        | 15 ++++
 .../components/widgets/cssmenu/CssMenuItem.java | 66 ++++++++++++------
 .../widgets/cssmenu/CssSubMenuItemsPanel.html   | 27 ++++----
 .../isis/applib/annotation/CssClassFa.java      | 34 +++++++++
 .../cssclassfa/cssclass/CssClassFaFacet.java    | 32 +++++++++
 .../cssclass/CssClassFaFacetAbstract.java       | 49 +++++++++++++
 .../CssClassFaFacetOnMemberAnnotation.java      | 30 ++++++++
 .../CssClassFaFacetOnMemberFactory.java         | 72 ++++++++++++++++++++
 .../CssClassFaFacetOnMemberFromProperties.java  | 35 ++++++++++
 .../metamodel/layoutmetadata/ActionRepr.java    |  1 +
 .../layoutmetadata/CssClassFaFacetRepr.java     | 22 ++++++
 .../json/LayoutMetadataReaderFromJson.java      | 37 +++-------
 .../dflt/ProgrammingModelFacetsJava5.java       |  2 +
 ...IsisMetaModelTest_constructWithServices.java | 10 ++-
 .../metamodel/app/IsisMetaModelTest_init.java   | 46 +++++++++++++
 ...er_newCollectionInteractionEvent_forAdd.java |  5 +-
 ...newCollectionInteractionEvent_forRemove.java |  7 +-
 ...ClassAnnotationOnMemberFacetFactoryTest.java | 14 ++--
 ...assFaAnnotationOnMemberFacetFactoryTest.java | 64 +++++++++++++++++
 .../cssclass/CssClassFaFacetAbstractTest.java   | 28 ++++++++
 ...ClassFaFacetOnTypeAnnotationFactoryTest.java | 55 +++++++++++++++
 ...ssClassFacetOnTypeAnnotationFactoryTest.java | 55 ---------------
 .../dom/src/main/java/app/ToDoItemAnalysis.java |  2 +-
 .../src/main/java/dom/todo/ToDoItem.layout.json | 43 ++++++++----
 .../java/dom/todo/ToDoItemContributions.java    |  2 +-
 .../dom/src/main/java/dom/todo/ToDoItems.java   |  3 +
 .../fixture/todo/ToDoItemsFixturesService.java  | 13 ++--
 35 files changed, 670 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
index ae0d73f..1b6cf29 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
@@ -33,8 +33,17 @@ public class LinkAndLabel implements Serializable {
     private final boolean prototype;
     private final String actionIdentifier;
     private final String cssClass;
+    private final String cssClassFa;
 
-    public LinkAndLabel(final AbstractLink link, final String label, String disabledReasonIfAny, final boolean blobOrClob, final boolean prototype, String identifier, final String cssClass) {
+    public LinkAndLabel(
+            final AbstractLink link,
+            final String label,
+            final String disabledReasonIfAny,
+            final boolean blobOrClob,
+            final boolean prototype,
+            final String identifier,
+            final String cssClass,
+            final String cssClassFa) {
         this.link = link;
         this.label = label;
         this.disabledReasonIfAny = disabledReasonIfAny;
@@ -42,6 +51,7 @@ public class LinkAndLabel implements Serializable {
         this.prototype = prototype;
         this.actionIdentifier = identifier;
         this.cssClass = cssClass;
+        this.cssClassFa = cssClassFa;
     }
 
     public AbstractLink getLink() {
@@ -71,4 +81,8 @@ public class LinkAndLabel implements Serializable {
     public String getCssClass() {
         return cssClass;
     }
+
+    public String getCssClassFa() {
+        return cssClassFa;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.css
index 9f1612a..11a9b2f 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.css
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.css
@@ -17,3 +17,6 @@
  *  under the License.
  */
 
+span .fa {
+    padding-right: 2px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.html
index 032c1fe..8e61dce 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.html
@@ -26,7 +26,8 @@
         <wicket:panel>
             <span wicket:id="additionalLinkList" class="additionalLinkList">
                 <span wicket:id="additionalLinkItem" class="additionalLinkItem">
-                    <a href="#" wicket:id="additionalLink" class="btn btn-xs btn-default">
+                    <a href="#" wicket:id="additionalLink" class="btn btn-sm btn-default">
+                        <span wicket:id="additionalLinkFontAwesome"/>
                         <span wicket:id="additionalLinkTitle" class="additionalLinkItem">[link title]</span>
                     </a>
                 </span>

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.java
index 4631e8a..b94beb1 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/additionallinks/AdditionalLinksPanel.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.wicket.ui.components.additionallinks;
 
 import java.util.List;
 
+import com.google.common.base.Strings;
 import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -35,6 +36,7 @@ import org.apache.isis.viewer.wicket.model.links.ListOfLinksModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
+import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
 /**
@@ -47,6 +49,7 @@ public class AdditionalLinksPanel extends PanelAbstract<ListOfLinksModel> {
 
     private static final String ID_ADDITIONAL_LINK_LIST = "additionalLinkList";
     private static final String ID_ADDITIONAL_LINK_ITEM = "additionalLinkItem";
+    private static final String ID_ADDITIONAL_LINK_FONT_AWESOME = "additionalLinkFontAwesome";
     private static final String ID_ADDITIONAL_LINK_TITLE = "additionalLinkTitle";
 
     public AdditionalLinksPanel(final String id, final List<LinkAndLabel> links) {
@@ -71,6 +74,15 @@ public class AdditionalLinksPanel extends PanelAbstract<ListOfLinksModel> {
                 
                 final AbstractLink link = linkAndLabel.getLink();
 
+                String cssClassFa = linkAndLabel.getCssClassFa();
+                if(Strings.isNullOrEmpty(cssClassFa)) {
+                    Components.permanentlyHide(link, ID_ADDITIONAL_LINK_FONT_AWESOME);
+                } else {
+                    Label dummy = new Label(ID_ADDITIONAL_LINK_FONT_AWESOME, "");
+                    link.addOrReplace(dummy);
+                    dummy.add(new CssClassAppender(cssClassFa));
+                }
+
                 Label viewTitleLabel = new Label(ID_ADDITIONAL_LINK_TITLE, linkAndLabel.getLabel());
                 String disabledReasonIfAny = linkAndLabel.getDisabledReasonIfAny();
                 if(disabledReasonIfAny != null) {

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
index a14300e..4d7a9a8 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/BulkActionsLinkFactory.java
@@ -207,8 +207,9 @@ final class BulkActionsLinkFactory implements ActionLinkFactory {
         final boolean explorationOrPrototype = CssMenuItem.isExplorationOrPrototype(objectAction);
         final String actionIdentifier = CssMenuItem.actionIdentifierFor(objectAction);
         final String cssClass = CssMenuItem.cssClassFor(objectAction);
+        final String cssClassFa = CssMenuItem.cssClassFaFor(objectAction);
 
-        return new LinkAndLabel(link, objectAction.getName(), null, false, explorationOrPrototype, actionIdentifier, cssClass);
+        return new LinkAndLabel(link, objectAction.getName(), null, false, explorationOrPrototype, actionIdentifier, cssClass, cssClassFa);
     }
     
     

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ActionLinkFactoryAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ActionLinkFactoryAbstract.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ActionLinkFactoryAbstract.java
index 0991f64..6655669 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ActionLinkFactoryAbstract.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ActionLinkFactoryAbstract.java
@@ -260,13 +260,15 @@ public abstract class ActionLinkFactoryAbstract implements ActionLinkFactory {
     }
 
     protected LinkAndLabel newLinkAndLabel(final ObjectAction action, final AbstractLink link, final String disabledReasonIfAny) {
+
         final String label = ObjectAction.Utils.nameFor(action);
         final boolean blobOrClob = CssMenuItem.returnsBlobOrClob(action);
         final boolean prototype = CssMenuItem.isExplorationOrPrototype(action);
         final String actionIdentifier = CssMenuItem.actionIdentifierFor(action);
         final String cssClass = CssMenuItem.cssClassFor(action);
-        
-        return new LinkAndLabel(link, label, disabledReasonIfAny, blobOrClob, prototype, actionIdentifier, cssClass);
+        final String cssClassFa = CssMenuItem.cssClassFaFor(action);
+
+        return new LinkAndLabel(link, label, disabledReasonIfAny, blobOrClob, prototype, actionIdentifier, cssClass, cssClassFa);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.css
index 16f0219..4d877b7 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.css
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.css
@@ -68,3 +68,21 @@
     -moz-border-radius: 6px 0 6px 6px;
     border-radius: 6px 0 6px 6px;
 }
+
+.dropdown-menu > li > a.menuLink {
+    display: inline-block;
+    padding-left: 0px;
+}
+
+.dropdown-menu > li > span.fa {
+    padding-left: 3px;
+}
+
+.dropdown-menu .fontAwesomeIcon {
+    min-width: 20px;
+}
+
+.dropdown-menu > li > a.menuLink.menuLinkSpacer {
+    padding-left: 24px;
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
index 425769d..ba2be98 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
@@ -12,7 +12,8 @@
             </li>
 
             <wicket:fragment wicket:id="leafItem">
-                <a wicket:id="menuLink"></a>
+                <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"/>
+                <a class="menuLink" wicket:id="menuLink"></a>
             </wicket:fragment>
 
             <wicket:fragment wicket:id="folderItem">

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
index 58f5d68..5134c54 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
@@ -4,6 +4,7 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.CssClassNameApp
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.button.DropdownAutoOpenJavaScriptReference;
 
 import java.util.List;
+import com.google.common.base.Strings;
 import org.apache.wicket.markup.head.CssHeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
@@ -16,6 +17,7 @@ import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.resource.CssResourceReference;
+import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
 /**
@@ -102,13 +104,26 @@ public class ApplicationActionsPanel extends Panel {
 
     private void addLeafItem(CssMenuItem menuItem, ListItem<CssMenuItem> listItem) {
         Fragment leafItem = new Fragment("content", "leafItem", ApplicationActionsPanel.this);
+
         AbstractLink subMenuItemLink = menuItem.getLink();
+
         subMenuItemLink.setBody(Model.of(menuItem.getName()));
         if (!menuItem.isEnabled()) {
             listItem.add(new CssClassNameAppender("disabled"));
         }
         leafItem.add(subMenuItemLink);
         listItem.add(leafItem);
+
+        String cssClassFa = menuItem.getCssClassFa();
+        if (Strings.isNullOrEmpty(cssClassFa)) {
+            Components.permanentlyHide(leafItem, "menuLinkFontAwesome");
+            subMenuItemLink.add(new CssClassAppender("menuLinkSpacer"));
+        } else {
+            Label dummy = new Label("menuLinkFontAwesome", "");
+            dummy.add(new CssClassAppender(cssClassFa));
+            leafItem.add(dummy);
+        }
+
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
index 247c5ce..8f0498e 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
@@ -22,6 +22,7 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.List;
+import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
@@ -41,6 +42,7 @@ import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChec
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.CssClassFaFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.runtime.system.context.IsisContext;
@@ -60,10 +62,6 @@ public class CssMenuItem implements Serializable {
 
     public static final String ID_MENU_LINK = "menuLink";
 
-    public void setCssClass(String cssClass) {
-        this.cssClass = cssClass;
-    }
-
     public static class Builder {
         private final CssMenuItem cssMenuItem;
 
@@ -122,8 +120,14 @@ public class CssMenuItem implements Serializable {
             return this;
         }
 
-        public void withCssClass(String cssClass) {
+        public Builder withCssClass(String cssClass) {
             cssMenuItem.setCssClass(cssClass);
+            return this;
+        }
+
+        public Builder withCssClassFa(String cssClassFa) {
+            cssMenuItem.setCssClassFa(cssClassFa);
+            return this;
         }
 
         /**
@@ -155,6 +159,7 @@ public class CssMenuItem implements Serializable {
 
     private String actionIdentifier;
     private String cssClass;
+    private String cssClassFa;
 
     private String description;
 
@@ -225,6 +230,19 @@ public class CssMenuItem implements Serializable {
         this.blobOrClob = blobOrClob;
     }
 
+    public void setCssClass(String cssClass) {
+        this.cssClass = cssClass;
+    }
+
+    public void setCssClassFa(String cssClassFa) {
+        this.cssClassFa = cssClassFa;
+    }
+
+    public String getCssClassFa() {
+        return cssClassFa;
+    }
+
+
     /**
      * Only populated if not {@link #isEnabled() enabled}.
      */
@@ -280,23 +298,17 @@ public class CssMenuItem implements Serializable {
         
         final DescribedAsFacet describedAsFacet = objectAction.getFacet(DescribedAsFacet.class);
         final String descriptionIfAny = describedAsFacet != null? describedAsFacet.value(): null;
-        
-        final CssClassFacet cssClassFacet = objectAction.getFacet(CssClassFacet.class);
-
-        final boolean blobOrClob = returnsBlobOrClob(objectAction);
-        final boolean prototype = isExplorationOrPrototype(objectAction);
-        final String actionIdentifier = actionIdentifierFor(objectAction);
 
         Builder builder = newSubMenuItem(actionLabel)
                 .link(link)
                 .describedAs(descriptionIfAny)
                 .enabled(reasonDisabledIfAny)
-                .returnsBlobOrClob(blobOrClob)
-                .prototyping(prototype)
-                .withActionIdentifier(actionIdentifier);
-        if (cssClassFacet != null) {
-            builder.withCssClass(cssClassFacet.value());
-        }
+                .returnsBlobOrClob(returnsBlobOrClob(objectAction))
+                .prototyping(isExplorationOrPrototype(objectAction))
+                .withActionIdentifier(actionIdentifierFor(objectAction))
+                .withCssClass(cssClassFor(objectAction))
+                .withCssClassFa(cssClassFaFor(objectAction));
+
         return builder;
     }
 
@@ -316,7 +328,7 @@ public class CssMenuItem implements Serializable {
         return action.getType().isExploration() || action.getType().isPrototype();
     }
 
-    public static String actionIdentifierFor(ObjectAction action) {
+    public static String actionIdentifierFor(final ObjectAction action) {
         @SuppressWarnings("unused")
         final Identifier identifier = action.getIdentifier();
         
@@ -325,11 +337,16 @@ public class CssMenuItem implements Serializable {
         return className + "-" + actionId;
     }
 
-    public static String cssClassFor(ObjectAction action) {
+    public static String cssClassFor(final ObjectAction action) {
         CssClassFacet cssClassFacet = action.getFacet(CssClassFacet.class);
         return cssClassFacet != null ? cssClassFacet.value() : null;
     }
 
+    public static String cssClassFaFor(final ObjectAction action) {
+        CssClassFaFacet cssClassFaFacet = action.getFacet(CssClassFaFacet.class);
+        return cssClassFaFacet != null ? cssClassFaFacet.value() : null;
+    }
+
     /**
      * Creates a {@link Builder} for a submenu item where the provided {@link ActionLinkFactory} is able to provide the target adapter.
      */
@@ -381,10 +398,19 @@ public class CssMenuItem implements Serializable {
                 link.add(new CssClassAppender("prototype"));
             }
             if(this.cssClass != null) {
-                markupContainer.add(new CssClassAppender(this.cssClass));
+                link.add(new CssClassAppender(this.cssClass));
             }
             link.add(new CssClassAppender(this.actionIdentifier));
 
+            String cssClassFa = getCssClassFa();
+            if (Strings.isNullOrEmpty(cssClassFa)) {
+                Components.permanentlyHide(link, "menuLinkFontAwesome");
+            } else {
+                Label dummy = new Label("menuLinkFontAwesome", "");
+                dummy.add(new CssClassAppender(cssClassFa));
+                link.add(dummy);
+            }
+
             // .. and hide label
             Components.permanentlyHide(markupContainer, CssMenuItem.ID_MENU_LABEL);
             return link;

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
index 45b87a1..da0bf1d 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
@@ -18,17 +18,18 @@
   under the License.
 -->
 <html xmlns:wicket="http://wicket.apache.org">
-	<body>
-		<wicket:panel>
-			<ul class="cssSubMenuItemsPanel">
-				<li wicket:id="subMenuItems" class="cssSubMenuItem">
-					<a wicket:id="menuLink" class="btn btn-xs btn-default">
-						<span wicket:id="menuLabel">[menu label]</span>
-					</a>
-					<p wicket:id="menuLabel">[menu label]</p>
-					<span wicket:id="subMenuItems">[subMenuItems]</span>
-				</li>
-			</ul>
-		</wicket:panel>
-	</body>
+<body>
+<wicket:panel>
+    <ul class="cssSubMenuItemsPanel">
+        <li wicket:id="subMenuItems" class="cssSubMenuItem">
+            <a wicket:id="menuLink" class="btn btn-xs btn-default">
+                <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"/>
+                <span wicket:id="menuLabel">[menu label]</span>
+            </a>
+            <p wicket:id="menuLabel">[menu label]</p>
+            <span wicket:id="subMenuItems">[subMenuItems]</span>
+        </li>
+    </ul>
+</wicket:panel>
+</body>
 </html>

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/applib/src/main/java/org/apache/isis/applib/annotation/CssClassFa.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/CssClassFa.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/CssClassFa.java
new file mode 100644
index 0000000..fcf1744
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/CssClassFa.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.applib.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates the <a href="http://fortawesome.github.io/Font-Awesome/">Font Awesome</a> CSS class to decorate an
+ * action (button or menu item).
+ */
+@Inherited
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CssClassFa {
+    String value();
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacet.java
new file mode 100644
index 0000000..388d47c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacet.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.core.metamodel.facets.members.cssclassfa.cssclass;
+
+import org.apache.isis.core.metamodel.facets.SingleStringValueFacet;
+
+/**
+ * The <a href="http://fortawesome.github.io/Font-Awesome/">Font Awesome</a> css class(es) for an action.
+ *
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to annotating the
+ * member with <tt>@CssClassFA</tt>.
+ */
+public interface CssClassFaFacet extends SingleStringValueFacet {
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstract.java
new file mode 100644
index 0000000..dae7dfc
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstract.java
@@ -0,0 +1,49 @@
+/*
+ *  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.core.metamodel.facets.members.cssclassfa.cssclass;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.SingleStringValueFacetAbstract;
+
+public class CssClassFaFacetAbstract extends SingleStringValueFacetAbstract implements CssClassFaFacet {
+
+    public CssClassFaFacetAbstract(final String value, final FacetHolder holder) {
+        super(type(), holder, sanitize(value));
+    }
+
+    static String sanitize(String value) {
+        return containsFa(value)? value: "fa " + value;
+    }
+
+    private static boolean containsFa(String value) {
+        final String[] split = value.split("\\s");
+        for (String s : split) {
+            if(s.trim().equals("fa")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static Class<? extends Facet> type() {
+        return CssClassFaFacet.class;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberAnnotation.java
new file mode 100644
index 0000000..7884a7b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberAnnotation.java
@@ -0,0 +1,30 @@
+/*
+ *  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.core.metamodel.facets.members.cssclassfa.cssclass.annotprop;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.CssClassFaFacetAbstract;
+
+public class CssClassFaFacetOnMemberAnnotation extends CssClassFaFacetAbstract {
+
+    public CssClassFaFacetOnMemberAnnotation(final String value, final FacetHolder holder) {
+        super(value, holder);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFactory.java
new file mode 100644
index 0000000..c5f6e35
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFactory.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.core.metamodel.facets.members.cssclassfa.cssclass.annotprop;
+
+import java.util.Properties;
+import org.apache.isis.applib.annotation.CssClassFa;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.ContributeeMemberFacetFactory;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.CssClassFaFacet;
+
+public class CssClassFaFacetOnMemberFactory extends FacetFactoryAbstract implements ContributeeMemberFacetFactory {
+
+    public CssClassFaFacetOnMemberFactory() {
+        super(FeatureType.ACTIONS_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessMethodContext processMethodContext) {
+        CssClassFaFacet cssClassFaFacet = createFromMetadataPropertiesIfPossible(processMethodContext);
+        if(cssClassFaFacet == null) {
+            cssClassFaFacet = createFromAnnotationIfPossible(processMethodContext);
+        }
+        
+        // no-op if null
+        FacetUtil.addFacet(cssClassFaFacet);
+    }
+
+    
+    @Override
+    public void process(ProcessContributeeMemberContext processMemberContext) {
+        CssClassFaFacet cssClassFaFacet = createFromMetadataPropertiesIfPossible(processMemberContext);
+        // no-op if null
+        FacetUtil.addFacet(cssClassFaFacet);
+    }
+
+    private static CssClassFaFacet createFromMetadataPropertiesIfPossible(
+            final ProcessContextWithMetadataProperties<? extends FacetHolder> pcwmp) {
+        
+        final FacetHolder holder = pcwmp.getFacetHolder();
+        
+        final Properties properties = pcwmp.metadataProperties("cssClassFa");
+        return properties != null ? new CssClassFaFacetOnMemberFromProperties(properties, holder) : null;
+    }
+
+    private CssClassFaFacet createFromAnnotationIfPossible(final ProcessMethodContext processMethodContext) {
+        final CssClassFa annotation = Annotations.getAnnotation(processMethodContext.getMethod(), CssClassFa.class);
+        return annotation != null ? new CssClassFaFacetOnMemberAnnotation(annotation.value(), processMethodContext.getFacetHolder()) : null;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFromProperties.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFromProperties.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFromProperties.java
new file mode 100644
index 0000000..ccae3f2
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/annotprop/CssClassFaFacetOnMemberFromProperties.java
@@ -0,0 +1,35 @@
+/*
+ *  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.core.metamodel.facets.members.cssclassfa.cssclass.annotprop;
+
+import java.util.Properties;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.CssClassFaFacetAbstract;
+
+public class CssClassFaFacetOnMemberFromProperties extends CssClassFaFacetAbstract {
+
+    public CssClassFaFacetOnMemberFromProperties(final Properties properties, final FacetHolder holder) {
+        super(valueFrom(properties), holder);
+    }
+
+    private static String valueFrom(Properties properties) {
+        return properties.getProperty("value");
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/ActionRepr.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/ActionRepr.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/ActionRepr.java
index 10adb26..ccc03c4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/ActionRepr.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/ActionRepr.java
@@ -26,4 +26,5 @@ public class ActionRepr {
     public NamedFacetRepr named;
     public DescribedAsFacetRepr describedAs;
     public CssClassFacetRepr cssClass;
+    public CssClassFaFacetRepr cssClassFa;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/CssClassFaFacetRepr.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/CssClassFaFacetRepr.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/CssClassFaFacetRepr.java
new file mode 100644
index 0000000..07e2c17
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/CssClassFaFacetRepr.java
@@ -0,0 +1,22 @@
+/**
+ *  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.core.metamodel.layoutmetadata;
+
+
+public class CssClassFaFacetRepr {
+    public String value;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
index f0d3f70..7e48e76 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
@@ -17,13 +17,7 @@
 package org.apache.isis.core.metamodel.layoutmetadata.json;
 
 import java.io.IOException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
+import java.util.*;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Strings;
@@ -33,7 +27,6 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-
 import org.apache.isis.applib.annotation.MemberGroupLayout.ColumnSpans;
 import org.apache.isis.applib.annotation.Render;
 import org.apache.isis.applib.annotation.Render.Type;
@@ -43,30 +36,18 @@ import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.core.commons.lang.ClassExtensions;
 import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
+import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
+import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetImpl;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
 import org.apache.isis.core.metamodel.facets.members.render.RenderFacet;
-import org.apache.isis.core.metamodel.facets.propparam.multiline.MultiLineFacet;
-import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 import org.apache.isis.core.metamodel.facets.object.paged.PagedFacet;
 import org.apache.isis.core.metamodel.facets.objpropparam.typicallen.TypicalLengthFacet;
+import org.apache.isis.core.metamodel.facets.propparam.multiline.MultiLineFacet;
 import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderFacetComparator;
-import org.apache.isis.core.metamodel.layoutmetadata.ActionRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.ColumnRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.CssClassFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.DescribedAsFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.DisabledFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.HiddenFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadata;
-import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
-import org.apache.isis.core.metamodel.layoutmetadata.MemberGroupRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.MemberRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.MultiLineFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.NamedFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.PagedFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.RenderFacetRepr;
-import org.apache.isis.core.metamodel.layoutmetadata.TypicalLengthFacetRepr;
+import org.apache.isis.core.metamodel.layoutmetadata.*;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.ObjectSpecifications;
@@ -74,8 +55,6 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecifications.MemberGroupLayou
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetImpl;
 
 public class LayoutMetadataReaderFromJson implements LayoutMetadataReader {
 
@@ -251,6 +230,10 @@ public class LayoutMetadataReaderFromJson implements LayoutMetadataReader {
         if(cssClass!= null) {
             props.setProperty(prefix +"." + actionName + ".cssClass.value", cssClass.value);
         }
+        final CssClassFaFacetRepr cssClassFa = actionRepr.cssClassFa;
+        if(cssClassFa != null) {
+            props.setProperty(prefix +"." + actionName + ".cssClassFa.value", cssClassFa.value);
+        }
     }
 
     public LayoutMetadata asLayoutMetadata(Class<?> domainClass) throws ReaderException {

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index a87e91a..c98f809 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -53,6 +53,7 @@ import org.apache.isis.core.metamodel.facets.collections.sortedby.annotation.Sor
 import org.apache.isis.core.metamodel.facets.collections.typeof.annotation.TypeOfFacetOnCollectionAnnotationFactory;
 import org.apache.isis.core.metamodel.facets.fallback.FallbackFacetFactory;
 import org.apache.isis.core.metamodel.facets.members.cssclass.annotprop.CssClassFacetOnMemberFactory;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.annotprop.CssClassFaFacetOnMemberFactory;
 import org.apache.isis.core.metamodel.facets.members.describedas.annotprop.DescribedAsFacetOnMemberFactory;
 import org.apache.isis.core.metamodel.facets.members.describedas.staticmethod.DescribedAsFacetStaticMethodFactory;
 import org.apache.isis.core.metamodel.facets.members.disabled.annotprop.DisabledFacetFactory;
@@ -356,6 +357,7 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(HiddenFacetOnMemberFactory.class);
         addFactory(CssClassFacetOnTypeAnnotationFactory.class);
         addFactory(CssClassFacetOnMemberFactory.class);
+        addFactory(CssClassFaFacetOnMemberFactory.class);
 
         addFactory(HiddenObjectFacetViaMethodFactory.class);
         addFactory(DisabledObjectFacetViaMethodFactory.class);

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_constructWithServices.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_constructWithServices.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_constructWithServices.java
index af6e00f..9f80e98 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_constructWithServices.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_constructWithServices.java
@@ -19,21 +19,19 @@
 
 package org.apache.isis.core.metamodel.app;
 
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
 import java.util.List;
-
 import org.jmock.auto.Mock;
 import org.junit.Rule;
 import org.junit.Test;
-
 import org.apache.isis.core.commons.matchers.IsisMatchers;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.runtimecontext.RuntimeContext;
 import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
 
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
 public class IsisMetaModelTest_constructWithServices {
 
     @Rule
@@ -65,7 +63,7 @@ public class IsisMetaModelTest_constructWithServices {
     public void shouldBeAbleToRegisterServices() {
         metaModel = new IsisMetaModel(mockContext, mockProgrammingModel, mockService1, mockService2);
         final List<Object> services = metaModel.getServices();
-        assertThat(services.size(), is(2));
+        assertThat(services.size(), is(3));
         assertThat(services, IsisMatchers.containsObjectOfType(SomeRepo.class));
         assertThat(services, IsisMatchers.containsObjectOfType(SomeOtherRepo.class));
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_init.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_init.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_init.java
index b8bd5ed..3fc502a 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_init.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/app/IsisMetaModelTest_init.java
@@ -27,10 +27,18 @@ import org.jmock.auto.Mock;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
 import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.adapter.QuerySubmitter;
+import org.apache.isis.core.metamodel.adapter.ServicesProvider;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
 import org.apache.isis.core.metamodel.facetdecorator.FacetDecorator;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.runtimecontext.RuntimeContext;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.spec.ObjectInstantiator;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
 import org.apache.isis.core.metamodel.specloader.classsubstitutor.ClassSubstitutor;
 import org.apache.isis.core.metamodel.specloader.collectiontyperegistry.CollectionTypeRegistry;
 import org.apache.isis.core.unittestsupport.jmocking.IsisActions;
@@ -47,6 +55,20 @@ public class IsisMetaModelTest_init {
     @Mock
     private ProgrammingModel mockProgrammingModelFacets;
     @Mock
+    private AuthenticationSessionProvider mockAuthenticationSessionProvider;
+    @Mock
+    private SpecificationLoader mockSpecificationLoader;
+    @Mock
+    private ServicesProvider mockServicesProvider;
+    @Mock
+    private ObjectInstantiator mockObjectInstantiator;
+    @Mock
+    private AdapterManager mockAdapterManager;
+    @Mock
+    private QuerySubmitter mockQuerySubmitter;
+    @Mock
+    private ServicesInjector mockDependencyInjector;
+    @Mock
     private FacetDecorator mockFacetDecorator;
     @Mock
     private ClassSubstitutor mockClassSubstitutor;
@@ -70,6 +92,30 @@ public class IsisMetaModelTest_init {
                 allowing(mockRuntimeContext).injectInto(with(any(Object.class)));
                 will(IsisActions.injectInto());
                 
+                allowing(mockRuntimeContext).getAuthenticationSessionProvider();
+                will(returnValue(mockAuthenticationSessionProvider));
+
+                allowing(mockRuntimeContext).getSpecificationLoader();
+                will(returnValue(mockSpecificationLoader));
+
+                allowing(mockRuntimeContext).getAdapterManager();
+                will(returnValue(mockAdapterManager));
+
+                allowing(mockRuntimeContext).getQuerySubmitter();
+                will(returnValue(mockQuerySubmitter));
+
+                allowing(mockRuntimeContext).getDependencyInjector();
+                will(returnValue(mockDependencyInjector));
+
+                allowing(mockRuntimeContext).getServicesProvider();
+                will(returnValue(mockServicesProvider));
+
+                allowing(mockRuntimeContext).getObjectInstantiator();
+                will(returnValue(mockObjectInstantiator));
+
+                allowing(mockRuntimeContext).getDeploymentCategory();
+                will(returnValue(DeploymentCategory.PRODUCTION));
+
                 oneOf(mockProgrammingModelFacets).init();
                 inSequence(initSequence);
                 

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forAdd.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forAdd.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forAdd.java
index 984a7da..659a964 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forAdd.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forAdd.java
@@ -19,6 +19,7 @@ package org.apache.isis.core.metamodel.facets;
 import java.util.Set;
 import org.junit.Test;
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.services.eventbus.AbstractInteractionEvent;
 import org.apache.isis.applib.services.eventbus.CollectionAddedToEvent;
 import org.apache.isis.applib.services.eventbus.CollectionInteractionEvent;
 
@@ -60,7 +61,7 @@ public class InteractionHelper_newCollectionInteractionEvent_forAdd {
         final Identifier identifier = Identifier.propertyOrCollectionIdentifier(SomeDomainObject.class, "references");
 
         final CollectionInteractionEvent<Object, Object> ev = new InteractionHelper(null).newCollectionInteractionEvent(
-                CollectionAddedToEvent.Default.class, null, identifier, sdo, CollectionInteractionEvent.Of.ADD_TO, other);
+                CollectionAddedToEvent.Default.class, AbstractInteractionEvent.Phase.EXECUTED, identifier, sdo, CollectionInteractionEvent.Of.ADD_TO, other);
         assertThat(ev.getSource(), is((Object)sdo));
         assertThat(ev.getIdentifier(), is(identifier));
         assertThat(ev.getOf(), is(CollectionInteractionEvent.Of.ADD_TO));
@@ -74,7 +75,7 @@ public class InteractionHelper_newCollectionInteractionEvent_forAdd {
         final Identifier identifier = Identifier.propertyOrCollectionIdentifier(SomeDomainObject.class, "references");
         
         final CollectionInteractionEvent<SomeDomainObject, SomeReferencedObject> ev = new InteractionHelper(null).newCollectionInteractionEvent(
-                SomeDomainObjectCollectionEvent.class, null, identifier, sdo, CollectionInteractionEvent.Of.ADD_TO, other);
+                SomeDomainObjectCollectionEvent.class, AbstractInteractionEvent.Phase.EXECUTED, identifier, sdo, CollectionInteractionEvent.Of.ADD_TO, other);
         assertThat(ev.getSource(), is(sdo));
         assertThat(ev.getIdentifier(), is(identifier));
         assertThat(ev.getOf(), is(CollectionInteractionEvent.Of.ADD_TO));

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forRemove.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forRemove.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forRemove.java
index e406a69..b1cd490 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forRemove.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/InteractionHelper_newCollectionInteractionEvent_forRemove.java
@@ -19,6 +19,7 @@ package org.apache.isis.core.metamodel.facets;
 import java.util.Set;
 import org.junit.Test;
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.services.eventbus.AbstractInteractionEvent;
 import org.apache.isis.applib.services.eventbus.CollectionInteractionEvent;
 import org.apache.isis.applib.services.eventbus.CollectionRemovedFromEvent;
 
@@ -46,7 +47,7 @@ public class InteractionHelper_newCollectionInteractionEvent_forRemove {
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(SomeDomainObject.class, "references");
 
         final CollectionInteractionEvent<Object, Object> ev = new InteractionHelper(null).newCollectionInteractionEvent(
-                CollectionRemovedFromEvent.Default.class, null, identifier, sdo, CollectionInteractionEvent.Of.REMOVE_FROM, other);
+                CollectionRemovedFromEvent.Default.class, AbstractInteractionEvent.Phase.EXECUTED, identifier, sdo, CollectionInteractionEvent.Of.REMOVE_FROM, other);
         assertThat(ev.getSource(), is((Object)sdo));
         assertThat(ev.getIdentifier(), is(identifier));
         assertThat(ev.getOf(), is(CollectionInteractionEvent.Of.REMOVE_FROM));
@@ -60,7 +61,7 @@ public class InteractionHelper_newCollectionInteractionEvent_forRemove {
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(SomeDomainObject.class, "references");
 
         final CollectionInteractionEvent<Object, Object> ev = new InteractionHelper(null).newCollectionInteractionEvent(
-                CollectionRemovedFromEvent.Default.class, null, identifier, sdo, CollectionInteractionEvent.Of.REMOVE_FROM, other);
+                CollectionRemovedFromEvent.Default.class, AbstractInteractionEvent.Phase.EXECUTED, identifier, sdo, CollectionInteractionEvent.Of.REMOVE_FROM, other);
         assertThat(ev.getSource(), is((Object)sdo));
         assertThat(ev.getIdentifier(), is(identifier));
         assertThat(ev.getOf(), is(CollectionInteractionEvent.Of.REMOVE_FROM));
@@ -74,7 +75,7 @@ public class InteractionHelper_newCollectionInteractionEvent_forRemove {
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(SomeDomainObject.class, "references");
 
         final CollectionInteractionEvent<SomeDomainObject, SomeReferencedObject> ev = new InteractionHelper(null).newCollectionInteractionEvent(
-                SomeDomainObjectCollectionRemovedFromEvent.class, null, identifier, sdo, CollectionInteractionEvent.Of.REMOVE_FROM, other);
+                SomeDomainObjectCollectionRemovedFromEvent.class, AbstractInteractionEvent.Phase.EXECUTED, identifier, sdo, CollectionInteractionEvent.Of.REMOVE_FROM, other);
         assertThat(ev.getSource(), is(sdo));
         assertThat(ev.getIdentifier(), is(identifier));
         assertThat(ev.getOf(), is(CollectionInteractionEvent.Of.REMOVE_FROM));

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclass/CssClassAnnotationOnMemberFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclass/CssClassAnnotationOnMemberFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclass/CssClassAnnotationOnMemberFacetFactoryTest.java
index e0267d0..a0ebfbe 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclass/CssClassAnnotationOnMemberFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclass/CssClassAnnotationOnMemberFacetFactoryTest.java
@@ -18,21 +18,17 @@
  */
 package org.apache.isis.core.metamodel.facets.members.cssclass;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
-
 import org.junit.Test;
-
 import org.apache.isis.applib.annotation.CssClass;
 import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
 import org.apache.isis.core.metamodel.facets.FacetedMethod;
-import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.members.cssclass.annotprop.CssClassFacetOnMemberFactory;
 
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
 public class CssClassAnnotationOnMemberFacetFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
 
     @Test
@@ -43,7 +39,7 @@ public class CssClassAnnotationOnMemberFacetFactoryTest extends AbstractFacetFac
 
         class Customer {
 
-            @CssClass("user")
+            @CssClass(value = "user")
             public String getName() {
                 return "Joe";
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaAnnotationOnMemberFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaAnnotationOnMemberFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaAnnotationOnMemberFacetFactoryTest.java
new file mode 100644
index 0000000..10743ee
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaAnnotationOnMemberFacetFactoryTest.java
@@ -0,0 +1,64 @@
+/*
+ *  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.core.metamodel.facets.members.cssclassfa;
+
+import java.lang.reflect.Method;
+import org.junit.Test;
+import org.apache.isis.applib.annotation.CssClassFa;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
+import org.apache.isis.core.metamodel.facets.FacetFactory;
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.CssClassFaFacet;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.CssClassFaFacetAbstract;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass.annotprop.CssClassFaFacetOnMemberFactory;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+public class CssClassFaAnnotationOnMemberFacetFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
+
+    @Test
+    public void testCssClassAnnotationPickedUpOnClass() {
+
+        final CssClassFaFacetOnMemberFactory facetFactory = new CssClassFaFacetOnMemberFactory();
+        facetFactory.setSpecificationLookup(mockSpecificationLoaderSpi);
+
+        class Customer {
+
+            @CssClassFa(value = "fa fa-foo")
+            public String foo() {
+                return "Joe";
+            }
+        }
+
+        expectNoMethodsRemoved();
+
+        final Method actionMethod = findMethod(Customer.class, "foo", new Class[] { });
+
+        facetedMethod = FacetedMethod.createForAction(Customer.class, actionMethod);
+        facetFactory.process(new FacetFactory.ProcessMethodContext(Customer.class, null, null, facetedMethod.getMethod(), mockMethodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(CssClassFaFacet.class);
+        assertThat(facet, is(not(nullValue())));
+        assertThat(facet instanceof CssClassFaFacetAbstract, is(true));
+        final CssClassFaFacetAbstract cssClassFacetAbstract = (CssClassFaFacetAbstract) facet;
+        assertThat(cssClassFacetAbstract.value(), equalTo("fa fa-foo"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstractTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstractTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstractTest.java
new file mode 100644
index 0000000..109cd42
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/cssclass/CssClassFaFacetAbstractTest.java
@@ -0,0 +1,28 @@
+package org.apache.isis.core.metamodel.facets.members.cssclassfa.cssclass;
+
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class CssClassFaFacetAbstractTest {
+
+    public static class Sanitize extends CssClassFaFacetAbstractTest {
+
+        @Test
+        public void present() throws Exception {
+            assertThat(CssClassFaFacetAbstract.sanitize("fa foo"), is("fa foo"));
+        }
+
+        @Test
+        public void presentAtEnd() throws Exception {
+            assertThat(CssClassFaFacetAbstract.sanitize("foo fa "), is("foo fa "));
+        }
+
+        @Test
+        public void missing() throws Exception {
+            assertThat(CssClassFaFacetAbstract.sanitize("foo"), is("fa foo"));
+        }
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFaFacetOnTypeAnnotationFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFaFacetOnTypeAnnotationFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFaFacetOnTypeAnnotationFactoryTest.java
new file mode 100644
index 0000000..6b354b3
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFaFacetOnTypeAnnotationFactoryTest.java
@@ -0,0 +1,55 @@
+/*
+ *  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.core.metamodel.facets.object.cssclass;
+
+import org.junit.Test;
+import org.apache.isis.applib.annotation.CssClass;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
+import org.apache.isis.core.metamodel.facets.FacetFactory;
+import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
+import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacetAbstract;
+import org.apache.isis.core.metamodel.facets.object.cssclass.annotation.CssClassFacetOnTypeAnnotationFactory;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+public class CssClassFaFacetOnTypeAnnotationFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
+
+    @Test
+    public void testCssClassAnnotationPickedUpOnClass() {
+
+        final CssClassFacetOnTypeAnnotationFactory facetFactory = new CssClassFacetOnTypeAnnotationFactory();
+        facetFactory.setSpecificationLookup(mockSpecificationLoaderSpi);
+
+        @CssClass("testClass")
+        class Customer {
+        }
+
+        expectNoMethodsRemoved();
+
+        facetFactory.process(new FacetFactory.ProcessClassContext(Customer.class, null, mockMethodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(CssClassFacet.class);
+        assertThat(facet, is(not(nullValue())));
+        assertThat(facet instanceof CssClassFacetAbstract, is(true));
+        final CssClassFacetAbstract cssClassFacetAbstract = (CssClassFacetAbstract) facet;
+        assertThat(cssClassFacetAbstract.value(), equalTo("testClass"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFacetOnTypeAnnotationFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFacetOnTypeAnnotationFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFacetOnTypeAnnotationFactoryTest.java
deleted file mode 100644
index 501d770..0000000
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/cssclass/CssClassFacetOnTypeAnnotationFactoryTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.facets.object.cssclass;
-
-import org.junit.Test;
-import org.apache.isis.applib.annotation.CssClass;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
-import org.apache.isis.core.metamodel.facets.FacetFactory;
-import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
-import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacetAbstract;
-import org.apache.isis.core.metamodel.facets.object.cssclass.annotation.CssClassFacetOnTypeAnnotationFactory;
-
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.assertThat;
-
-public class CssClassFacetOnTypeAnnotationFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
-
-    @Test
-    public void testCssClassAnnotationPickedUpOnClass() {
-
-        final CssClassFacetOnTypeAnnotationFactory facetFactory = new CssClassFacetOnTypeAnnotationFactory();
-        facetFactory.setSpecificationLookup(mockSpecificationLoaderSpi);
-
-        @CssClass("testClass")
-        class Customer {
-        }
-
-        expectNoMethodsRemoved();
-
-        facetFactory.process(new FacetFactory.ProcessClassContext(Customer.class, null, mockMethodRemover, facetedMethod));
-
-        final Facet facet = facetedMethod.getFacet(CssClassFacet.class);
-        assertThat(facet, is(not(nullValue())));
-        assertThat(facet instanceof CssClassFacetAbstract, is(true));
-        final CssClassFacetAbstract cssClassFacetAbstract = (CssClassFacetAbstract) facet;
-        assertThat(cssClassFacetAbstract.value(), equalTo("testClass"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java b/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
index 6149bb3..3286ae6 100644
--- a/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
+++ b/example/application/todoapp/dom/src/main/java/app/ToDoItemAnalysis.java
@@ -74,7 +74,7 @@ public class ToDoItemAnalysis {
         Later,
         Unknown,
     }
-    
+
     @Named("By Date Range")
     @Bookmarkable
     @ActionSemantics(Of.SAFE)

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.layout.json
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.layout.json b/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.layout.json
index f15424d..a4c9460 100644
--- a/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.layout.json
+++ b/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.layout.json
@@ -33,7 +33,11 @@
                                     "value": "Update"
                                 }
                             },
-                            "analyseCategory": {}
+                            "analyseCategory": {
+                                "cssClassFa": {
+                                     "value": "fa-pie-chart"
+                                }
+                            }
                         }
                     },
                     "ownedBy": {
@@ -46,10 +50,11 @@
                                 "describedAs": {
                                     "value": "Mark this todo item as having been completed"
                                 },
-                                "cssClass": { "value": "x-highlight" }
+                                "cssClassFa": { "value": "fa fa-check-square" }
                             },
                             "notYetCompleted": {
-                                "named": { "value": "Not done" }
+                                "named": { "value": "Not done" },
+                              "cssClassFa": { "value": "fa-reply fa-flip-vertical" }
                             },
                             "scheduleExplicitly": {
                             },
@@ -84,8 +89,12 @@
                 "members": {
                      "relativePriority": {
                         "actions": {
-                            "previous": {},
-                            "next": {}
+                            "previous": {
+                                "cssClassFa": { "value": "fa-step-backward" }
+                            },
+                            "next": {
+                                "cssClassFa": { "value": "fa-step-forward" }
+                            }
                         }
                     },
                     "dueBy": {
@@ -98,9 +107,8 @@
                     "cost": {
                         "actions": {
                             "updateCost":{
-                                "named": {
-                                    "value": "Update"
-                                }
+                                "named": { "value": "Update" },
+                                "cssClassFa": { "value": "fa-dollar" }
                             }
                         }
                     },
@@ -135,9 +143,12 @@
             "dependencies": {
                 "disabled": {},
                 "actions": {
-                    "add":{},
+                    "add":{
+                        "cssClassFa": { "value": "fa-plus-square" }
+                    },
                     "remove": {
-                        "cssClass": { "value": "x-caution" }
+                        "cssClass": { "value": "x-caution" },
+                        "cssClassFa": { "value": "fa-minus-square" }
                     }
                 },
                 "paged": {
@@ -162,15 +173,17 @@
     "actions": {
         "totalCost": {},
         "delete": {
-            "cssClass": { "value": "x-caution" }
+            "cssClass": { "value": "btn btn-danger" },
+            "cssClassFa": { "value": "fa-trash fa-lg" }
         },
         "duplicate": {
-	        "named": {
-	            "value": "Clone"
-	        },
+	          "named": {
+	              "value": "Clone"
+	          },
             "describedAs": {
                 "value": "Create a new todo item from this one"
-            }
+            },
+            "cssClassFa": { "value": "fa-copy fa-lg" }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItemContributions.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItemContributions.java b/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItemContributions.java
index d38cd7f..e30378c 100644
--- a/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItemContributions.java
+++ b/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItemContributions.java
@@ -115,7 +115,7 @@ public class ToDoItemContributions extends AbstractFactoryAndRepository {
     }
 
     // //////////////////////////////////////
-    
+
     @DescribedAs("The previous item not yet completed")
     @NotInServiceMenu
     @ActionSemantics(Of.SAFE)

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItems.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItems.java b/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItems.java
index b4f8428..70cf8a0 100644
--- a/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItems.java
+++ b/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItems.java
@@ -36,6 +36,7 @@ import org.apache.isis.applib.services.clock.ClockService;
 public class ToDoItems {
 
     //region > notYetComplete (action)
+    @CssClassFa("fa-list")
     @Bookmarkable
     @ActionSemantics(Of.SAFE)
     @MemberOrder(sequence = "10")
@@ -57,6 +58,7 @@ public class ToDoItems {
     //endregion
 
     //region > complete (action)
+    @CssClassFa("fa-check-square-o")
     @ActionSemantics(Of.SAFE)
     @MemberOrder(sequence = "20")
     public List<ToDoItem> complete() {
@@ -114,6 +116,7 @@ public class ToDoItems {
     //endregion
 
     //region > newToDo (action)
+    @CssClassFa("fa-plus")
     @MemberOrder(sequence = "5")
     public ToDoItem newToDo(
             final @RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*") @Named("Description") String description, 

http://git-wip-us.apache.org/repos/asf/isis/blob/673a514e/example/application/todoapp/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
----------------------------------------------------------------------
diff --git a/example/application/todoapp/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java b/example/application/todoapp/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
index 2bcc1b7..f4e219a 100644
--- a/example/application/todoapp/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
+++ b/example/application/todoapp/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
@@ -21,10 +21,7 @@ package fixture.todo;
 import fixture.todo.scenarios.RecreateToDoItemsAndCompleteSeveralForCurrent;
 
 import java.util.List;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.applib.annotation.Named;
-import org.apache.isis.applib.annotation.Prototype;
+import org.apache.isis.applib.annotation.*;
 import org.apache.isis.applib.fixturescripts.FixtureResult;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
@@ -40,6 +37,12 @@ public class ToDoItemsFixturesService extends FixtureScripts {
         super("fixture.todo");
     }
 
+    @CssClassFa("fa-bolt")
+    @Override
+    public List<FixtureResult> runFixtureScript(FixtureScript fixtureScript, @Named("Parameters") @DescribedAs("Script-specific parameters (if any).  The format depends on the script implementation (eg key=value, CSV, JSON, XML etc)") @MultiLine(numberOfLines = 10) @Optional String parameters) {
+        return super.runFixtureScript(fixtureScript, parameters);
+    }
+
     @Override
     public FixtureScript default0RunFixtureScript() {
         return findFixtureScriptFor(RecreateToDoItemsAndCompleteSeveralForCurrent.class);
@@ -59,7 +62,7 @@ public class ToDoItemsFixturesService extends FixtureScripts {
 
     @Prototype
     @MemberOrder(sequence="20")
-    public Object recreateToDoItemsForCurrentAndReturnFirst() {
+    public Object recreateToDoItemsReturnFirst() {
         final List<FixtureResult> run = findFixtureScriptFor(RecreateToDoItemsAndCompleteSeveralForCurrent.class).run(null);
         return run.get(0).getObject();
     }