You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/04/07 21:59:42 UTC

[isis] 01/10: Adding type TranslationContext, adding context qualifiers for tabs and memberOrderNames, fixing overriding NamedFacetTranslated in grid

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 374a5d8cee0317734b53f5bc68678723d341d133
Author: mwhesse <mw...@gmail.com>
AuthorDate: Tue Apr 6 14:32:18 2021 +0700

    Adding type TranslationContext, adding context qualifiers for tabs and memberOrderNames, fixing overriding NamedFacetTranslated in grid
---
 .../exceprecog/ExceptionRecognizerAbstract.java    |  3 +-
 .../applib/services/exceprecog/Recognition.java    |  4 +-
 .../applib/services/i18n/TranslatableString.java   |  2 +-
 .../applib/services/i18n/TranslationContext.java   | 72 +++++++++++++++++
 .../applib/services/i18n/TranslationService.java   |  4 +-
 .../applib/services/message/MessageService.java    |  7 +-
 .../services/i18n/TranslatableStringTest.java      |  6 +-
 .../_testing/TranslationService_forTesting.java    |  5 +-
 .../invocation/ActionDomainEventFacetAbstract.java |  5 +-
 .../ActionParameterValidationFacetViaMethod.java   |  6 +-
 .../method/ActionValidationFacetViaMethod.java     |  5 +-
 .../ActionValidationFacetViaMethodFactory.java     |  3 +-
 .../all/i18n/DescribedAsFacetTranslated.java       |  5 +-
 .../facets/all/i18n/NamedFacetTranslated.java      |  5 +-
 .../facets/all/i18n/PluralFacetTranslated.java     |  3 +-
 .../facets/all/i18n/TranslationFacetFactory.java   | 11 +--
 .../method/DisableForContextFacetViaMethod.java    |  5 +-
 .../DisableForContextFacetViaMethodFactory.java    |  3 +-
 .../members/order/MemberOrderFacetAbstract.java    |  9 ++-
 .../annotprop/MemberOrderFacetAnnotation.java      |  4 +-
 .../order/annotprop/MemberOrderFacetFactory.java   |  4 +-
 .../annotprop/MemberOrderFacetProperties.java      |  8 +-
 .../order/annotprop/MemberOrderFacetXml.java       |  6 +-
 .../choices/enums/EnumValueSemanticsProvider.java  |  5 +-
 .../method/DisabledObjectFacetViaMethod.java       |  5 +-
 .../DisabledObjectFacetViaMethodFactory.java       |  5 +-
 ...ainObjectLayoutAnnotationUsingTitleUiEvent.java | 12 +--
 .../title/methods/TitleFacetViaMethodsFactory.java |  3 +-
 .../title/methods/TitleFacetViaTitleMethod.java    |  6 +-
 .../method/ValidateObjectFacetMethod.java          |  6 +-
 .../method/ValidateObjectFacetMethodFactory.java   |  3 +-
 .../MustSatisfySpecificationFacetAbstract.java     |  3 +-
 .../mustsatisfyspec/SpecificationEvaluator.java    |  5 +-
 .../ActionParameterDisabledFacetViaMethod.java     |  5 +-
 ...tionParameterDisabledFacetViaMethodFactory.java |  3 +-
 .../ActionParameterValidationFacetViaMethod.java   |  5 +-
 ...onParameterValidationFacetViaMethodFactory.java |  3 +-
 .../modify/PropertyDomainEventFacetAbstract.java   |  5 +-
 .../method/PropertyValidateFacetViaMethod.java     |  6 +-
 .../PropertyValidateFacetViaMethodFactory.java     |  3 +-
 .../services/grid/GridSystemServiceAbstract.java   | 38 +++++++--
 .../services/message/MessageServiceNoop.java       |  7 +-
 .../title/TitlesAndTranslationsValidator.java      |  9 ++-
 .../ordering/memberorder/DeweyOrderSetTest.java    | 90 +++++++++++-----------
 .../MemberOrderAnnotationFacetFactoryTest.java     |  3 +-
 .../memberorder/MemberOrderComparatorTest.java     | 59 +++++++-------
 .../isis/core/runtimeservices/i18n/po/Block.java   |  1 +
 .../core/runtimeservices/i18n/po/PoAbstract.java   |  5 +-
 .../core/runtimeservices/i18n/po/PoDisabled.java   |  5 +-
 .../core/runtimeservices/i18n/po/PoReader.java     | 10 +--
 .../core/runtimeservices/i18n/po/PoWriter.java     |  9 ++-
 .../i18n/po/TranslationServicePo.java              |  5 +-
 .../message/MessageServiceDefault.java             | 11 +--
 .../core/runtimeservices/i18n/po/PoReaderTest.java | 41 +++++-----
 .../model/decorator/confirm/ConfirmUiModel.java    | 15 ++--
 .../components/layout/bs3/tabs/TabGroupPanel.java  |  6 +-
 .../viewer/integration/LocalizerForIsis.java       |  5 +-
 .../viewer/integration/WebRequestCycleForIsis.java |  5 +-
 58 files changed, 385 insertions(+), 207 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java b/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
index 3850c42..fb3d891 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
@@ -27,6 +27,7 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.exceptions.TranslatableException;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -117,7 +118,7 @@ public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer
             if(ex instanceof TranslatableException) {
                 final TranslatableException translatableException = (TranslatableException) ex;
                 final TranslatableString translatableMessage = translatableException.getTranslatableMessage();
-                final String translationContext = translatableException.getTranslationContext();
+                final TranslationContext translationContext = TranslationContext.ofTrEx(translatableException);
                 if(translatableMessage != null && translationContext != null) {
                     return translatableMessage.translate(translationService, translationContext);
                 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/Recognition.java b/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/Recognition.java
index 8bf9327..60101bf 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/Recognition.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/exceprecog/Recognition.java
@@ -22,6 +22,7 @@ import java.util.Optional;
 
 import javax.annotation.Nullable;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 
 import lombok.NonNull;
@@ -131,8 +132,9 @@ public class Recognition {
         if (x == null || translationService == null) {
             return x;
         }
+        TranslationContext context = TranslationContext.ofClass(Recognition.class);
         return translationService.translate(
-                Recognition.class.getName(), x);
+        		context, x);
     }
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java b/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java
index fdeaa9f..3753b7c 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java
@@ -188,7 +188,7 @@ public final class TranslatableString {
      * @param translationService
      * @param context
      */
-    public String translate(final TranslationService translationService, final String context) {
+    public String translate(final TranslationService translationService, final TranslationContext context) {
 
         final String translatedText =
                 !isPluralForm()
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationContext.java b/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationContext.java
new file mode 100644
index 0000000..d92cbe7
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationContext.java
@@ -0,0 +1,72 @@
+package org.apache.isis.applib.services.i18n;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.exceptions.TranslatableException;
+import org.apache.isis.applib.spec.AbstractSpecification;
+import org.apache.isis.applib.spec.Specification;
+
+public interface TranslationContext {
+
+	String stringify();
+	
+	static class DefaultTranslationContext implements TranslationContext {
+		final String ctx;
+		DefaultTranslationContext(String ctx) {
+			this.ctx = ctx;
+		}
+		@Override
+		public String stringify() {
+			return ctx;
+		}		
+	}
+	
+	static TranslationContext ofSimpleStringIdentifier(String simple) {
+		return new DefaultTranslationContext(simple);
+	}	
+	
+	static TranslationContext ofClass(Class<?> contextClass) {
+		return new DefaultTranslationContext(contextClass.getName());
+	}
+	
+	static TranslationContext ofClassAndMethodName(Class<?> contextClass, String methodName) {
+		return new DefaultTranslationContext(contextClass.getName() + "#" + methodName);
+	}	
+	
+	static TranslationContext ofTrEx(TranslatableException translatableException) {
+		return new DefaultTranslationContext(translatableException.getTranslationContext());
+	}
+
+	static TranslationContext ofIdentifier(Identifier identifier) {
+		return new DefaultTranslationContext(identifier.getTranslationContext());
+	}
+
+	static TranslationContext ofIdentifierFullIdentity(Identifier identifier) {
+		return new DefaultTranslationContext(identifier.getFullIdentityString());
+	}
+
+	static TranslationContext ofTitleMethod(Method titleMethod) {
+		return new DefaultTranslationContext(titleMethod.getDeclaringClass().getName() + "#" + titleMethod.getName() + "()");
+	}
+
+	static TranslationContext ofEnum(Enum<?> objectAsEnum) {
+		return new DefaultTranslationContext(objectAsEnum.getClass().getName() + "#" + objectAsEnum.name());
+	}
+
+	static TranslationContext ofDisabledObjectMethod(Method disabledObjectMethod) {
+		return new DefaultTranslationContext(disabledObjectMethod.getDeclaringClass().getName() + "#" + disabledObjectMethod.getName() + "()");
+	}
+
+	static TranslationContext ofIdentifierForTab(Identifier identifier) {
+		return new DefaultTranslationContext(identifier.getTranslationContext() + "~tabName");
+	}
+	
+	static TranslationContext ofIdentifierForMemberOrderName(Identifier identifier) {
+		return new DefaultTranslationContext(identifier.getTranslationContext() + "~memberOrderName");
+	}	
+
+	static TranslationContext ofClassForMemberOrderName(Class<?> class1) {
+		return new DefaultTranslationContext(class1.getName() + "~memberOrderName");
+	}
+}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java b/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java
index 1b908a9..60a345b 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java
@@ -45,7 +45,7 @@ public interface TranslationService {
      * @param text
      */
     String translate(
-            final String context,
+            final TranslationContext context,
             final String text);
 
     /**
@@ -62,7 +62,7 @@ public interface TranslationService {
      * @param num - whether to return the translation of the singular (if =1) or of the plural (if != 1)
      */
     String translate(
-            final String context,
+            final TranslationContext context,
             final String singularText,
             final String pluralText,
             int num);
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/message/MessageService.java b/api/applib/src/main/java/org/apache/isis/applib/services/message/MessageService.java
index 44f3c9c..c561806 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/message/MessageService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/message/MessageService.java
@@ -20,6 +20,7 @@
 package org.apache.isis.applib.services.message;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 
 /**
  * Allows domain objects to raise information, warning or error messages.
@@ -78,7 +79,7 @@ public interface MessageService {
      */
     String informUser(
             TranslatableString message,
-            final String translationContext);
+            final TranslationContext translationContext);
 
     /**
      * Warn the user about a situation with the specified message.
@@ -127,7 +128,7 @@ public interface MessageService {
      */
     String warnUser(
             TranslatableString message,
-            final String translationContext);
+            final TranslationContext translationContext);
 
     /**
      * Notify the user of an application error with the specified message.
@@ -176,6 +177,6 @@ public interface MessageService {
      */
     String raiseError(
             TranslatableString message,
-            final String translationContext);
+            final TranslationContext translationContext);
 
 }
diff --git a/api/applib/src/test/java/org/apache/isis/applib/services/i18n/TranslatableStringTest.java b/api/applib/src/test/java/org/apache/isis/applib/services/i18n/TranslatableStringTest.java
index 70b0699..225c131 100644
--- a/api/applib/src/test/java/org/apache/isis/applib/services/i18n/TranslatableStringTest.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/services/i18n/TranslatableStringTest.java
@@ -88,7 +88,7 @@ public class TranslatableStringTest {
         public void singularForm() throws Exception {
             // given
             final String simpleText = "text to translate";
-            final String someContext = "someContext";
+            final TranslationContext someContext = TranslationContext.ofSimpleStringIdentifier("someContext");
             final String translation = "the translation";
 
             final TranslatableString ts = TranslatableString.tr(simpleText);
@@ -109,7 +109,7 @@ public class TranslatableStringTest {
             // given
             final String singularText = "singular text to translate";
             final String pluralText = "plural text to translate";
-            final String someContext = "someContext";
+            final TranslationContext someContext = TranslationContext.ofSimpleStringIdentifier("someContext");
             final String translation = "the translation";
 
             final TranslatableString ts = TranslatableString.trn(singularText, pluralText, 1);
@@ -130,7 +130,7 @@ public class TranslatableStringTest {
             // given
             final String singularText = "singular text to translate";
             final String pluralText = "plural text to translate";
-            final String someContext = "someContext";
+            final TranslationContext someContext = TranslationContext.ofSimpleStringIdentifier("someContext");
             final String translation = "the translation";
             final int number = 2; // != 1
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/TranslationService_forTesting.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/TranslationService_forTesting.java
index 6d33a2c..f8f32c7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/TranslationService_forTesting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/_testing/TranslationService_forTesting.java
@@ -19,17 +19,18 @@
 package org.apache.isis.core.metamodel._testing;
 
 import org.apache.isis.applib.services.i18n.Mode;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 
 public class TranslationService_forTesting implements TranslationService {
 
     @Override
-    public String translate(String context, String text) {
+    public String translate(TranslationContext context, String text) {
         return text;
     }
 
     @Override
-    public String translate(String context, String singularText, String pluralText, int num) {
+    public String translate(TranslationContext context, String singularText, String pluralText, int num) {
         return num==1 ? singularText : pluralText;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
index 000bb28..0224941 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
@@ -22,6 +22,7 @@ package org.apache.isis.core.metamodel.facets.actions.action.invocation;
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.assertions._Assert;
@@ -47,7 +48,7 @@ implements ActionDomainEventFacet {
 
     @Getter @Setter private Class<? extends ActionDomainEvent<?>> eventType;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
     private final DomainEventHelper domainEventHelper;
 
     public ActionDomainEventFacetAbstract(
@@ -59,7 +60,7 @@ implements ActionDomainEventFacet {
 
         this.translationService = getTranslationService();
         // sadness: same as in TranslationFactory
-        this.translationContext = ((IdentifiedHolder)holder).getIdentifier().getTranslationContext();
+        this.translationContext = TranslationContext.ofIdentifier(((IdentifiedHolder)holder).getIdentifier());
 
         domainEventHelper = DomainEventHelper.ofServiceRegistry(getServiceRegistry());
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java
index 7ffbb95..0d0a946 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -36,9 +37,10 @@ public class ActionParameterValidationFacetViaMethod extends ActionParameterVali
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
-    public ActionParameterValidationFacetViaMethod(final Method method, final TranslationService translationService, final String translationContext, final FacetHolder holder) {
+    public ActionParameterValidationFacetViaMethod(final Method method, final TranslationService translationService, 
+    		final TranslationContext translationContext, final FacetHolder holder) {
         super(holder);
         this.method = method;
         this.translationService = translationService;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
index 1408e92..1b4276d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Optional;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -39,13 +40,13 @@ public class ActionValidationFacetViaMethod extends ActionValidationFacetAbstrac
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
     private final Optional<Constructor<?>> ppmFactory;
 
     public ActionValidationFacetViaMethod(
             final Method method, 
             final TranslationService translationService, 
-            final String translationContext, 
+            final TranslationContext translationContext, 
             Optional<Constructor<?>> ppmFactory, 
             final FacetHolder holder) {
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
index c27825f..cdd6f95 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
@@ -22,6 +22,7 @@ package org.apache.isis.core.metamodel.facets.actions.validate.method;
 import java.util.EnumSet;
 
 import org.apache.isis.applib.exceptions.unrecoverable.MetaModelException;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.ActionSupport;
@@ -75,7 +76,7 @@ extends MethodPrefixBasedFacetFactoryAbstract  {
 
             val ppmFactory = searchResult.getPpmFactory();
             val translationService = getTranslationService();
-            val translationContext = facetHolder.getIdentifier().getTranslationContext();
+            TranslationContext translationContext = TranslationContext.ofIdentifier(facetHolder.getIdentifier());
             super.addFacet(
                     new ActionValidationFacetViaMethod(
                             validateMethod, translationService, translationContext, ppmFactory, facetHolder));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/DescribedAsFacetTranslated.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/DescribedAsFacetTranslated.java
index 9aa024b..050717a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/DescribedAsFacetTranslated.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/DescribedAsFacetTranslated.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.all.i18n;
 
 import java.util.Map;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
@@ -28,12 +29,12 @@ import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
 
 public class DescribedAsFacetTranslated extends FacetAbstract implements DescribedAsFacet {
 
-    private final String context;
+    private final TranslationContext context;
     private final String originalText;
     private final TranslationService translationService;
 
     public DescribedAsFacetTranslated(
-            final String context, final String originalText,
+            final TranslationContext context, final String originalText,
             final TranslationService translationService,
             final IdentifiedHolder holder) {
         super(DescribedAsFacet.class, holder, Derivation.NOT_DERIVED);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/NamedFacetTranslated.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/NamedFacetTranslated.java
index 95e6260..03bcc24 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/NamedFacetTranslated.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/NamedFacetTranslated.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.all.i18n;
 
 import java.util.Map;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
@@ -29,11 +30,11 @@ import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 public class NamedFacetTranslated extends FacetAbstract implements NamedFacet {
 
     final TranslationService translationService;
-    String context;
+    TranslationContext context;
     String originalText;
 
     public NamedFacetTranslated(
-            final String context, final String originalText,
+            final TranslationContext context, final String originalText,
             final TranslationService translationService,
             final IdentifiedHolder facetHolder) {
         super(NamedFacet.class, facetHolder, Derivation.NOT_DERIVED);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/PluralFacetTranslated.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/PluralFacetTranslated.java
index 87928e5..b47ef75 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/PluralFacetTranslated.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/PluralFacetTranslated.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.all.i18n;
 
 import java.util.Map;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.commons.StringExtensions;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
@@ -30,7 +31,7 @@ import org.apache.isis.core.metamodel.facets.object.plural.PluralFacet;
 public class PluralFacetTranslated extends FacetAbstract implements PluralFacet {
 
     private final TranslationService translationService;
-    private String context;
+    private TranslationContext context;
     private String originalText;
 
     public PluralFacetTranslated(final NamedFacetTranslated facet, final FacetHolder facetHolder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
index 98eca48..1875101 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/i18n/TranslationFacetFactory.java
@@ -19,6 +19,7 @@
 package org.apache.isis.core.metamodel.facets.all.i18n;
 
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -40,7 +41,7 @@ extends FacetFactoryAbstract {
         final FacetHolder facetHolder = processClassContext.getFacetHolder();
         if(facetHolder instanceof IdentifiedHolder) {
             final IdentifiedHolder holder = (IdentifiedHolder) facetHolder;
-            final String context = holder.getIdentifier().getClassName();
+            final TranslationContext context = TranslationContext.ofIdentifier(holder.getIdentifier()); // .getClassName();
             translateName(holder, context);
             translateDescription(holder, context);
         }
@@ -50,7 +51,7 @@ extends FacetFactoryAbstract {
     public void process(final ProcessMethodContext processMethodContext) {
         final IdentifiedHolder holder = processMethodContext.getFacetHolder();
 
-        final String context = holder.getIdentifier().getTranslationContext();
+        final TranslationContext context = TranslationContext.ofIdentifier(holder.getIdentifier()); // .getTranslationContext();
         translateName(holder, context);
         translateDescription(holder, context);
     }
@@ -59,14 +60,14 @@ extends FacetFactoryAbstract {
     public void processParams(final ProcessParameterContext processParameterContext) {
         final IdentifiedHolder holder = processParameterContext.getFacetHolder();
 
-        final String context = holder.getIdentifier().getFullIdentityString();
+        final TranslationContext context = TranslationContext.ofIdentifierFullIdentity(holder.getIdentifier()); // .getFullIdentityString();
         translateName(holder, context);
         translateDescription(holder, context);
     }
 
     // //////////////////////////////////////
 
-    void translateName(final IdentifiedHolder facetHolder, final String context) {
+    void translateName(final IdentifiedHolder facetHolder, final TranslationContext context) {
         final NamedFacet facet = facetHolder.getFacet(NamedFacet.class);
         if(facet == null) {
             // not expected...
@@ -84,7 +85,7 @@ extends FacetFactoryAbstract {
         super.addFacet(facetTranslated);
     }
 
-    void translateDescription(final FacetHolder facetHolder, final String context) {
+    void translateDescription(final FacetHolder facetHolder, final TranslationContext context) {
 
         final IdentifiedHolder holder = (IdentifiedHolder) facetHolder;
         final DescribedAsFacet facet = facetHolder.getFacet(DescribedAsFacet.class);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
index 21d9060..74a0f76 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -38,12 +39,12 @@ implements ImperativeFacet {
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
     public DisableForContextFacetViaMethod(
             final Method method,
             final TranslationService translationService, 
-            final String translationContext,
+            final TranslationContext translationContext,
             final FacetHolder holder) {
         super(holder);
         this.method = method;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
index 37bfb51..65afcd2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.members.disabled.method;
 
 import java.lang.reflect.Method;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -85,7 +86,7 @@ extends MethodPrefixBasedFacetFactoryAbstract  {
         final FacetHolder facetHolder = processMethodContext.getFacetHolder();
         final TranslationService translationService = getTranslationService();
         // sadness: same logic as in I18nFacetFactory
-        final String translationContext = ((IdentifiedHolder)facetHolder).getIdentifier().getTranslationContext();
+        final TranslationContext translationContext = TranslationContext.ofIdentifier(((IdentifiedHolder)facetHolder).getIdentifier()); // .getTranslationContext();
         super.addFacet(new DisableForContextFacetViaMethod(disableMethod, translationService, translationContext, facetHolder));
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/MemberOrderFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/MemberOrderFacetAbstract.java
index 2fb226e..b2d6c03 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/MemberOrderFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/MemberOrderFacetAbstract.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.members.order;
 
 import java.util.Map;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -40,11 +41,12 @@ public abstract class MemberOrderFacetAbstract extends FacetAbstract implements
     private final String sequence;
 
     public MemberOrderFacetAbstract(
+    		TranslationContext context,
             final String name,
             final String sequence,
             final TranslationService translationService,
             final FacetHolder holder) {
-        this(translatedValueElse(name, "", translationService, holder),
+        this(translatedValueElse(context, name, "", translationService, holder),
                 sequence,
                 holder);
     }
@@ -60,6 +62,7 @@ public abstract class MemberOrderFacetAbstract extends FacetAbstract implements
     }
 
     private static String translatedValueElse(
+    		TranslationContext context,
             final String name,
             final String defaultValue,
             final TranslationService translationService,
@@ -68,8 +71,8 @@ public abstract class MemberOrderFacetAbstract extends FacetAbstract implements
         if (nullOrEmpty) {
             return defaultValue;
         } else {
-            final IdentifiedHolder identifiedHolder = (IdentifiedHolder) holder;
-            final String context = identifiedHolder.getIdentifier().getClassName();
+            // final IdentifiedHolder identifiedHolder = (IdentifiedHolder) holder;
+            // final String context = identifiedHolder.getIdentifier().getClassName();
             return translationService.translate(context, name);
         }
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetAnnotation.java
index eda0ace..cea600f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetAnnotation.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.facets.members.order.annotprop;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacetAbstract;
@@ -26,10 +27,11 @@ import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacetAbstr
 public class MemberOrderFacetAnnotation extends MemberOrderFacetAbstract {
 
     public MemberOrderFacetAnnotation(
+    		TranslationContext context,
             final String name,
             final String sequence,
             final TranslationService translationService, final FacetHolder holder) {
-        super(name, sequence, translationService, holder);
+        super(context, name, sequence, translationService, holder);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetFactory.java
index 3c27822..4597946 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetFactory.java
@@ -20,6 +20,7 @@
 package org.apache.isis.core.metamodel.facets.members.order.annotprop;
 
 import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
@@ -49,8 +50,9 @@ extends FacetFactoryAbstract  {
 //        _Assert.assertEquals("expected same", annotation,
 //                Annotations.getAnnotation(processMethodContext.getMethod(), MemberOrder.class));
         
-        if (annotation != null) {
+        if (annotation != null) {        	
             return new MemberOrderFacetAnnotation(
+            		TranslationContext.ofIdentifier(processMethodContext.getFacetHolder().getIdentifier()),
                     annotation.name(),
                     annotation.sequence(),
                     getTranslationService(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetProperties.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetProperties.java
index 5f6945e..ba1d622 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetProperties.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetProperties.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.members.order.annotprop;
 
 import java.util.Properties;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacetAbstract;
@@ -28,10 +29,11 @@ import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacetAbstr
 public class MemberOrderFacetProperties extends MemberOrderFacetAbstract {
 
     public MemberOrderFacetProperties(
+    		TranslationContext context,
             final Properties properties,
             final TranslationService translationService,
             final FacetHolder holder) {
-        this(name(properties), sequence(properties), translationService, holder);
+        this(context, name(properties), sequence(properties), translationService, holder);
     }
 
     private static String sequence(final Properties properties) {
@@ -42,8 +44,8 @@ public class MemberOrderFacetProperties extends MemberOrderFacetAbstract {
         return properties.getProperty("name");
     }
 
-    private MemberOrderFacetProperties(final String name, final String sequence, final TranslationService translationService, final FacetHolder holder) {
-        super(name, sequence, translationService, holder);
+    private MemberOrderFacetProperties(TranslationContext context,final String name, final String sequence, final TranslationService translationService, final FacetHolder holder) {
+        super(context, name, sequence, translationService, holder);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetXml.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetXml.java
index 7830d32..4b2f21c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetXml.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/order/annotprop/MemberOrderFacetXml.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.facets.members.order.annotprop;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacetAbstract;
@@ -26,10 +27,11 @@ import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacetAbstr
 public class MemberOrderFacetXml extends MemberOrderFacetAbstract {
 
     public MemberOrderFacetXml(
-            final String name,
+    		TranslationContext context,
+    		final String name,
             final String sequence,
             final TranslationService translationService, final FacetHolder holder) {
-        super(name, sequence, translationService, holder);
+        super(context, name, sequence, translationService, holder);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
index 5cdb5e9..f457a36 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.adapters.EncoderDecoder;
 import org.apache.isis.applib.adapters.Parser;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.util.Enums;
 import org.apache.isis.core.metamodel.commons.MethodExtensions;
@@ -116,7 +117,7 @@ public class EnumValueSemanticsProvider<T extends Enum<T>> extends ValueSemantic
 
         if (titleMethod != null) {
             // sadness: same as in TranslationFactory
-            final String translationContext = titleMethod.getDeclaringClass().getName() + "#" + titleMethod.getName() + "()";
+            final TranslationContext translationContext = TranslationContext.ofTitleMethod(titleMethod);
 
             try {
                 final Object returnValue = MethodExtensions.invoke(titleMethod, object);
@@ -135,7 +136,7 @@ public class EnumValueSemanticsProvider<T extends Enum<T>> extends ValueSemantic
 
         // simply translate the enum constant's name
         Enum<?> objectAsEnum = (Enum<?>) object;
-        final String translationContext = object.getClass().getName() + "#" + objectAsEnum.name();
+        final TranslationContext translationContext = TranslationContext.ofEnum(objectAsEnum); // object.getClass().getName() + "#" + objectAsEnum.name();
         final String friendlyNameOfEnum = Enums.getFriendlyNameOf(objectAsEnum.name());
         return translationService.translate(translationContext, friendlyNameOfEnum);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
index e9fcc36..5182dd3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.Identifier.Type;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -39,12 +40,12 @@ public class DisabledObjectFacetViaMethod extends DisabledObjectFacetAbstract im
 
     private final Method method;
     private TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
     public DisabledObjectFacetViaMethod(
             final Method method,
             final TranslationService translationService,
-            final String translationContext,
+            final TranslationContext translationContext,
             final FacetHolder holder) {
         super(holder);
         this.method = method;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
index 052febe..5782a25 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethodFactory.java
@@ -20,6 +20,7 @@
 package org.apache.isis.core.metamodel.facets.object.disabled.method;
 
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -69,7 +70,9 @@ public class DisabledObjectFacetViaMethodFactory extends MethodPrefixBasedFacetF
 
         val translationService = getTranslationService();
         // sadness: same logic as in I18nFacetFactory
-        val translationContext = ((IdentifiedHolder)facetHolder).getIdentifier().getClassName();
+        // val translationContext = ((IdentifiedHolder)facetHolder).getIdentifier().getClassName();
+        TranslationContext translationContext = TranslationContext.ofDisabledObjectMethod(method);
+        
         FacetUtil.addFacet(new DisabledObjectFacetViaMethod(method, translationService, translationContext, facetHolder));
 
         processClassContext.removeMethod(method);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java
index b8b8212..4fda6b0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.events.ui.TitleUiEvent;
 import org.apache.isis.applib.exceptions.UnrecoverableException;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.core.config.IsisConfiguration;
@@ -74,12 +75,12 @@ public class TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent extends
 
     private final Class<? extends TitleUiEvent<?>> titleUiEventClass;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
     private final MetamodelEventService metamodelEventService;
 
     public TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent(
             final Class<? extends TitleUiEvent<?>> titleUiEventClass,
-                    final String translationContext,
+                    final TranslationContext translationContext,
                     final MetamodelEventService metamodelEventService,
                     final FacetHolder holder) {
         super(holder);
@@ -130,10 +131,11 @@ public class TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent extends
         return null;
     }
 
-    private static String translationContextFor(final FacetHolder facetHolder) {
-        if(facetHolder instanceof ObjectSpecification) {
+    private static TranslationContext translationContextFor(final FacetHolder facetHolder) {
+        if(facetHolder instanceof ObjectSpecification) {        	
             val facetHolderAsSpec = (ObjectSpecification) facetHolder; // bit naughty...
-            return facetHolderAsSpec.getCorrespondingClass().getCanonicalName();    
+            // return facetHolderAsSpec.getCorrespondingClass().getCanonicalName();
+            return TranslationContext.ofIdentifier(facetHolderAsSpec.getIdentifier());
         } 
         return null;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
index 14af9a2..42a03ec 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaMethodsFactory.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.object.title.methods;
 
 import java.lang.reflect.Method;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -63,7 +64,7 @@ public class TitleFacetViaMethodsFactory extends MethodPrefixBasedFacetFactoryAb
             processClassContext.removeMethod(method);
             final TranslationService translationService = getTranslationService();
             // sadness: same as in TranslationFactory
-            final String translationContext = method.getDeclaringClass().getName() + "#" + method.getName() + "()";
+            final TranslationContext translationContext = TranslationContext.ofTitleMethod(method); // .getDeclaringClass().getName() + "#" + method.getName() + "()";
 
             final TitleFacetViaTitleMethod facet = new TitleFacetViaTitleMethod(method, translationService, translationContext, facetHolder);
             FacetUtil.addFacet(facet);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
index b7a9c3c..6401ce5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -40,9 +41,10 @@ public class TitleFacetViaTitleMethod extends TitleFacetAbstract implements Impe
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
-    public TitleFacetViaTitleMethod(final Method method, final TranslationService translationService, final String translationContext, final FacetHolder holder) {
+    public TitleFacetViaTitleMethod(final Method method, final TranslationService translationService, 
+    		final TranslationContext translationContext, final FacetHolder holder) {
         super(holder);
         this.method = method;
         this.translationService = translationService;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
index 5a78559..76a1983 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethod.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -36,9 +37,10 @@ public class ValidateObjectFacetMethod extends ValidateObjectFacetAbstract imple
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
-    public ValidateObjectFacetMethod(final Method method, final TranslationService translationService, final String translationContext, final FacetHolder holder) {
+    public ValidateObjectFacetMethod(final Method method, final TranslationService translationService, 
+    		final TranslationContext translationContext, final FacetHolder holder) {
         super(holder);
         this.method = method;
         this.translationService = translationService;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
index 9428024..6b008bd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/validating/validateobject/method/ValidateObjectFacetMethodFactory.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.object.validating.validateobject.m
 
 import java.lang.reflect.Method;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -52,7 +53,7 @@ public class ValidateObjectFacetMethodFactory extends MethodPrefixBasedFacetFact
         if (method != null) {
             val translationService = getTranslationService();
             // sadness: same as in TranslationFactory
-            val translationContext = ((IdentifiedHolder)facetHolder).getIdentifier().getClassName();
+            TranslationContext translationContext = TranslationContext.ofIdentifier(((IdentifiedHolder)facetHolder).getIdentifier()); // .getClassName();
             FacetUtil.addFacet(new ValidateObjectFacetMethod(method, translationService, translationContext, facetHolder));
             processClassContext.removeMethod(method);
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
index 667d2a8..17e776c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/MustSatisfySpecificationFacetAbstract.java
@@ -26,6 +26,7 @@ import java.util.Objects;
 import java.util.stream.Collectors;
 
 import org.apache.isis.applib.services.factory.FactoryService;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.spec.Specification;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -63,7 +64,7 @@ public abstract class MustSatisfySpecificationFacetAbstract extends FacetAbstrac
 
         final TranslationService translationService = getTranslationService();
         // sadness: same as in TranslationFactory
-        final String translationContext = ((IdentifiedHolder) holder).getIdentifier().getTranslationContext();
+        final TranslationContext translationContext = TranslationContext.ofIdentifier(((IdentifiedHolder) holder).getIdentifier()); // .getTranslationContext();
 
         specificationEvaluator = new SpecificationEvaluator(translationService, translationContext);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/SpecificationEvaluator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/SpecificationEvaluator.java
index aa2b445..3f188c8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/SpecificationEvaluator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/mustsatisfyspec/SpecificationEvaluator.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.objectvalue.mustsatisfyspec;
 import java.util.List;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.spec.Specification;
 import org.apache.isis.applib.spec.Specification2;
@@ -33,11 +34,11 @@ import org.apache.isis.applib.util.ReasonBuffer;
 public class SpecificationEvaluator {
 
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
     public SpecificationEvaluator(
             final TranslationService translationService,
-            final String translationContext) {
+            final TranslationContext translationContext) {
         this.translationService = translationService;
         this.translationContext = translationContext;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java
index 79efcef..08da13a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Optional;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -41,13 +42,13 @@ implements ImperativeFacet {
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
     private final Optional<Constructor<?>> ppmFactory;
 
     public ActionParameterDisabledFacetViaMethod(
             final Method method,
             final TranslationService translationService,
-            final String translationContext,
+            final TranslationContext translationContext,
             final Optional<Constructor<?>> ppmFactory, 
             final FacetHolder holder) {
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethodFactory.java
index abca700..d9be520 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethodFactory.java
@@ -22,6 +22,7 @@ package org.apache.isis.core.metamodel.facets.param.disable.method;
 import java.util.EnumSet;
 
 import org.apache.isis.applib.exceptions.unrecoverable.MetaModelException;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.MethodLiteralConstants;
@@ -81,7 +82,7 @@ extends MethodPrefixBasedFacetFactoryAbstract  {
             
             // add facets directly to parameters, not to actions
             val paramAsHolder = parameters.get(paramNum);
-            val translationContext = paramAsHolder.getIdentifier().getFullIdentityString();
+            TranslationContext translationContext = TranslationContext.ofIdentifierFullIdentity(paramAsHolder.getIdentifier()); // .getFullIdentityString();
             val ppmFactory = searchResult.getPpmFactory();
             val translationService = getMetaModelContext().getTranslationService();
             
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java
index 03eace7..44ad8d7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Optional;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -41,13 +42,13 @@ implements ImperativeFacet {
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
     private final Optional<Constructor<?>> ppmFactory;
 
     public ActionParameterValidationFacetViaMethod(
             final Method method, 
             final TranslationService translationService, 
-            final String translationContext, 
+            final TranslationContext translationContext, 
             final Optional<Constructor<?>> ppmFactory, 
             final FacetHolder holder) {
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethodFactory.java
index 8b83101..82e52cc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethodFactory.java
@@ -22,6 +22,7 @@ package org.apache.isis.core.metamodel.facets.param.validate.method;
 import java.util.EnumSet;
 
 import org.apache.isis.applib.exceptions.unrecoverable.MetaModelException;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.MethodLiteralConstants;
@@ -81,7 +82,7 @@ public class ActionParameterValidationFacetViaMethodFactory extends MethodPrefix
             
             // add facets directly to parameters, not to actions
             val paramAsHolder = parameters.get(paramNum);
-            val translationContext = paramAsHolder.getIdentifier().getFullIdentityString();
+            val translationContext = TranslationContext.ofIdentifierFullIdentity(paramAsHolder.getIdentifier());
             val ppmFactory = searchResult.getPpmFactory();
             val translationService = getMetaModelContext().getTranslationService();
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java
index f913cde..1a8c587 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java
@@ -25,6 +25,7 @@ import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.PropertyDomainEvent;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -46,7 +47,7 @@ extends SingleClassValueFacetAbstract implements PropertyDomainEventFacet {
 
     private final PropertyOrCollectionAccessorFacet getterFacetIfAny;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
     /**
      * @param getterFacetIfAny - will be null if this is for a mixin {@link OneToOneAssociationMixedIn}.
@@ -62,7 +63,7 @@ extends SingleClassValueFacetAbstract implements PropertyDomainEventFacet {
 
         this.translationService = getTranslationService();
         // sadness: same as in TranslationFactory
-        this.translationContext = ((IdentifiedHolder)holder).getIdentifier().getTranslationContext();
+        this.translationContext = TranslationContext.ofIdentifier(((IdentifiedHolder)holder).getIdentifier()); // .getTranslationContext();
 
         domainEventHelper = DomainEventHelper.ofServiceRegistry(getServiceRegistry());
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java
index 65c70c8..e4665eb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -36,9 +37,10 @@ public class PropertyValidateFacetViaMethod extends PropertyValidateFacetAbstrac
 
     private final Method method;
     private final TranslationService translationService;
-    private final String translationContext;
+    private final TranslationContext translationContext;
 
-    public PropertyValidateFacetViaMethod(final Method method, final TranslationService translationService, final String translationContext, final FacetHolder holder) {
+    public PropertyValidateFacetViaMethod(final Method method, final TranslationService translationService, 
+    		final TranslationContext translationContext, final FacetHolder holder) {
         super(holder);
         this.method = method;
         this.translationService = translationService;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
index d782f5f..ce3ad44 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.facets.properties.validating.method;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.MethodFinder2;
@@ -63,7 +64,7 @@ public class PropertyValidateFacetViaMethodFactory extends MethodPrefixBasedFace
         val facetHolder = processMethodContext.getFacetHolder();
         val translationService = getTranslationService();
         // sadness: same as in TranslationFactory
-        val translationContext = facetHolder.getIdentifier().getTranslationContext();
+        val translationContext = TranslationContext.ofIdentifier(facetHolder.getIdentifier()); // .getTranslationContext();
         super.addFacet(
                 new PropertyValidateFacetViaMethod(
                         validateMethod, translationService, translationContext, facetHolder));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridSystemServiceAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridSystemServiceAbstract.java
index 21dc89f..34856a2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridSystemServiceAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridSystemServiceAbstract.java
@@ -35,6 +35,7 @@ import org.apache.isis.applib.layout.component.FieldSet;
 import org.apache.isis.applib.layout.component.PropertyLayoutData;
 import org.apache.isis.applib.layout.grid.Grid;
 import org.apache.isis.applib.services.grid.GridSystemService;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.message.MessageService;
@@ -42,6 +43,7 @@ import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.core.config.environment.IsisSystemEnvironment;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
 import org.apache.isis.core.metamodel.facets.actions.layout.ActionPositionFacetForActionXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.BookmarkPolicyFacetForActionXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.CssClassFaFacetForActionXml;
@@ -51,6 +53,7 @@ import org.apache.isis.core.metamodel.facets.actions.layout.HiddenFacetForAction
 import org.apache.isis.core.metamodel.facets.actions.layout.NamedFacetForActionXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.PromptStyleFacetForActionXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.RedirectFacetFromActionXml;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.collections.layout.CssClassFacetForCollectionXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.DefaultViewFacetForCollectionXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.DescribedAsFacetForCollectionXml;
@@ -210,6 +213,7 @@ implements GridSystemService<G> {
                 }
 
                 String memberOrderName = null;
+                TranslationContext translationContext = TranslationContext.ofIdentifierForMemberOrderName(objectAction.getIdentifier());
                 int memberOrderSequence;
                 if(actionLayoutDataOwner instanceof FieldSet) {
                     final FieldSet fieldSet = (FieldSet) actionLayoutDataOwner;
@@ -218,7 +222,7 @@ implements GridSystemService<G> {
                         final String propertyId = propertyLayoutData.getId();
                         // any will do; choose the first one that we know is valid
                         if(oneToOneAssociationById.containsKey(propertyId)) {
-                            memberOrderName = propertyLayoutData.getId();
+                            memberOrderName = propertyLayoutData.getId();                            
                             break;
                         }
                     }
@@ -234,11 +238,12 @@ implements GridSystemService<G> {
                 } else {
                     // don't add: any existing metadata should be preserved
                     memberOrderName = null;
+                    translationContext = null;
                     memberOrderSequence = actionDomainObjectSequence++;
                 }
                 if(memberOrderName != null) {
                     addOrReplaceFacet(
-                            new MemberOrderFacetXml(memberOrderName, "" + memberOrderSequence, translationService, objectAction));
+                            new MemberOrderFacetXml(translationContext, memberOrderName, "" + memberOrderSequence, translationService, objectAction));
                 }
 
                 // fix up the action position if required
@@ -265,7 +270,11 @@ implements GridSystemService<G> {
                 addOrReplaceFacet(CssClassFaFacetForActionXml.create(actionLayoutData, objectAction));
                 addOrReplaceFacet(DescribedAsFacetForActionXml.create(actionLayoutData, objectAction));
                 addOrReplaceFacet(HiddenFacetForActionXml.create(actionLayoutData, objectAction));
-                addOrReplaceFacet(NamedFacetForActionXml.create(actionLayoutData, objectAction));
+                // preserve translations
+                NamedFacet existingNamedFacet = objectAction.getFacet(NamedFacet.class);
+                if(existingNamedFacet == null) {
+                    addOrReplaceFacet(NamedFacetForActionXml.create(actionLayoutData, objectAction));
+                }
                 addOrReplaceFacet(PromptStyleFacetForActionXml.create(actionLayoutData, objectAction));
                 addOrReplaceFacet(RedirectFacetFromActionXml.create(actionLayoutData, objectAction));
             }
@@ -282,7 +291,11 @@ implements GridSystemService<G> {
                 addOrReplaceFacet(HiddenFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
                 addOrReplaceFacet(LabelAtFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
                 addOrReplaceFacet(MultiLineFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
-                addOrReplaceFacet(NamedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+                // preserve translations
+                NamedFacet existingNamedFacet = oneToOneAssociation.getFacet(NamedFacet.class);
+                if(existingNamedFacet == null) {
+                	addOrReplaceFacet(NamedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+                }
                 addOrReplaceFacet(PromptStyleFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
                 addOrReplaceFacet(RenderedAdjustedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
                 addOrReplaceFacet(UnchangingFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
@@ -293,9 +306,13 @@ implements GridSystemService<G> {
                 // table columns are shown correctly (by fieldset, then property order within that fieldset).
                 final FieldSet fieldSet = propertyLayoutData.getOwner();
                 final String groupName = fieldSet.getName();
+                                
+                final IdentifiedHolder identifiedHolder = (IdentifiedHolder) oneToOneAssociation;
+                final TranslationContext translationContext = TranslationContext.ofIdentifierForMemberOrderName(identifiedHolder.getIdentifier());
+                // TranslationContext translationContext = TranslationContext.ofIdentifierForMemberOrderName(oneToOneAssociation.getIdentifier());
                 final String sequence = "" + (propertySequence.incrementAndGet());
                 addOrReplaceFacet(
-                        new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
+                        new MemberOrderFacetXml(translationContext, groupName, sequence, translationService, oneToOneAssociation));
             }
 
             @Override
@@ -308,16 +325,21 @@ implements GridSystemService<G> {
                 addOrReplaceFacet(CssClassFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
                 addOrReplaceFacet(DefaultViewFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
                 addOrReplaceFacet(DescribedAsFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
-                addOrReplaceFacet(HiddenFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
-                addOrReplaceFacet(NamedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+                addOrReplaceFacet(HiddenFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));                
+                // preserve translations
+                NamedFacet existingNamedFacet = oneToManyAssociation.getFacet(NamedFacet.class);
+                if(existingNamedFacet == null) {
+                    addOrReplaceFacet(NamedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+                }
                 addOrReplaceFacet(PagedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
                 addOrReplaceFacet(SortedByFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
 
                 // @MemberOrder#name based on the collection's id (so that each has a single "member group")
                 final String groupName = collectionLayoutData.getId();
+                TranslationContext translationContext = TranslationContext.ofIdentifierForMemberOrderName(oneToManyAssociation.getIdentifier());
                 final String sequence = "" + collectionSequence++;
                 addOrReplaceFacet(
-                        new MemberOrderFacetXml(groupName, sequence, translationService, oneToManyAssociation));
+                        new MemberOrderFacetXml(translationContext, groupName, sequence, translationService, oneToManyAssociation));
             }
         });
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/message/MessageServiceNoop.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/message/MessageServiceNoop.java
index 0260686..c02a145 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/message/MessageServiceNoop.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/message/MessageServiceNoop.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.services.message;
 import javax.enterprise.inject.Vetoed;
 
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.message.MessageService;
 
 @Vetoed // can be used via producer (optional) 
@@ -40,7 +41,7 @@ public class MessageServiceNoop implements MessageService {
     }
 
     @Override
-    public String informUser(TranslatableString message, String translationContext) {
+    public String informUser(TranslatableString message, TranslationContext translationContext) {
         throw notSupported();
     }
 
@@ -57,7 +58,7 @@ public class MessageServiceNoop implements MessageService {
     }
 
     @Override
-    public String warnUser(TranslatableString message, String translationContext) {
+    public String warnUser(TranslatableString message, TranslationContext translationContext) {
         throw notSupported();
     }
 
@@ -74,7 +75,7 @@ public class MessageServiceNoop implements MessageService {
     }
 
     @Override
-    public String raiseError(TranslatableString message, String translationContext) {
+    public String raiseError(TranslatableString message, TranslationContext translationContext) {
         throw notSupported();
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
index 33e854a..fde69d7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.metamodel.services.title;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.title.TitleService;
 import org.apache.isis.commons.internal.base._Blackhole;
@@ -143,10 +144,14 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
         val translationService = serviceRegistry.lookupServiceElseFail(TranslationService.class);
         
         // as used by the Wicket UI?
-        final String context = "org.apache.isis.core.interaction.session.InteractionFactory";
+        // final TranslationContext context = "org.apache.isis.core.interaction.session.InteractionFactory";
+        
+        // see @ConfirmUiModel#translate()
+        final TranslationContext context = TranslationContext.ofClass(MessageRegistry.class);
+        
         final MessageRegistry messageRegistry = new MessageRegistry();
         for (String message : messageRegistry.listMessages()) {
-
+        	
             try {
 
                 val translatedMessage = translationService.translate(context, message);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/DeweyOrderSetTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/DeweyOrderSetTest.java
index a081e67..1cb7490 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/DeweyOrderSetTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/DeweyOrderSetTest.java
@@ -27,6 +27,7 @@ import org.jmock.api.Action;
 import org.jmock.api.Invocation;
 import org.junit.Rule;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.context._Context;
@@ -86,6 +87,8 @@ public class DeweyOrderSetTest extends TestCase {
 
     @Rule
     public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
+    
+	static TranslationContext ctx = TranslationContext.ofSimpleStringIdentifier("test");
 
     @Override
     protected void setUp() {
@@ -94,7 +97,7 @@ public class DeweyOrderSetTest extends TestCase {
 
         mockTranslationService = context.mock(TranslationService.class);
         context.checking(new Expectations() {{
-            allowing(mockTranslationService).translate(with(any(String.class)), with(any(String.class)));
+            allowing(mockTranslationService).translate(with(any(TranslationContext.class)), with(any(String.class)));
             will(new Action() {
                 @Override
                 public Object invoke(final Invocation invocation) throws Throwable {
@@ -115,8 +118,9 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testDefaultGroup() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
+    	    	
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
         assertEquals("", orderSet.getGroupName());
@@ -125,8 +129,8 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testDefaultGroupSize() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
         assertEquals(2, orderSet.size());
@@ -135,8 +139,8 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testDefaultGroupTwoMembersSorted() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
         assertEquals(lastNameMember, orderSet.elementList().get(0));
@@ -144,8 +148,8 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testTwoMembersAtDefaultGroupOtherWay() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, firstNameMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, firstNameMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameAndFirstName);
         assertEquals(firstNameMember, orderSet.elementList().get(0));
@@ -153,11 +157,11 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testWithChildGroupDefaultGroupName() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
-        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", mockTranslationService, houseNumberMember));
-        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", mockTranslationService, streetNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "1", mockTranslationService, houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "2", mockTranslationService, streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "3", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
         assertEquals("", orderSet.getGroupName());
@@ -166,11 +170,11 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testWithChildGroupSize() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
-        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", mockTranslationService, houseNumberMember));
-        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", mockTranslationService, streetNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "1", mockTranslationService, houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "2", mockTranslationService, streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "3", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
         assertEquals(1, orderSet.children().size());
@@ -178,11 +182,11 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testWithChildGroupChildsGroupName() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
-        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", mockTranslationService, houseNumberMember));
-        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", mockTranslationService, streetNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "1", mockTranslationService, houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "2", mockTranslationService, streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "3", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
         final List<?> children = orderSet.children();
@@ -193,11 +197,11 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testWithChildGroupChildsGroupSize() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
-        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "1", mockTranslationService, houseNumberMember));
-        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "2", mockTranslationService, streetNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "3", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "1", mockTranslationService, houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "2", mockTranslationService, streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "3", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
         final DeweyOrderSet childOrderSet = orderSet.children().get(0);
@@ -206,11 +210,11 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testWithChildGroupChildsGroupElementOrdering() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
-        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "6", mockTranslationService, houseNumberMember));
-        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "5", mockTranslationService, streetNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "4", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "6", mockTranslationService, houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "5", mockTranslationService, streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "4", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
         final DeweyOrderSet childOrderSet = orderSet.children().get(0);
@@ -220,11 +224,11 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testWithChildGroupOrderedAtEnd() {
-        houseNumberMember.addFacet(new MemberOrderFacetAnnotation("address", "6", mockTranslationService, houseNumberMember));
-        streetNameMember.addFacet(new MemberOrderFacetAnnotation("address", "5", mockTranslationService, streetNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "4", mockTranslationService, postalTownMember));
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "3", mockTranslationService, lastNameMember));
-        firstNameMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, firstNameMember));
+        houseNumberMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "6", mockTranslationService, houseNumberMember));
+        streetNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "5", mockTranslationService, streetNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "4", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "3", mockTranslationService, lastNameMember));
+        firstNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, firstNameMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(nameAndAddressMembers);
         assertEquals(firstNameMember, orderSet.elementList().get(0));
@@ -244,16 +248,16 @@ public class DeweyOrderSetTest extends TestCase {
     }
 
     public void testDefaultGroupMixOfAnnotatedAndNotSize() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("address", "2", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "address", "2", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameFirstNameAndPostalTown);
         assertEquals(3, orderSet.elementList().size());
     }
 
     public void testDefaultGroupMixOfAnnotatedAndNotOrderedWithAnnotatedFirst() {
-        lastNameMember.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, lastNameMember));
-        postalTownMember.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, postalTownMember));
+        lastNameMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, lastNameMember));
+        postalTownMember.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, postalTownMember));
 
         final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(lastNameFirstNameAndPostalTown);
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java
index c119fec..cae4b90 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderAnnotationFacetFactoryTest.java
@@ -29,6 +29,7 @@ import org.jmock.api.Invocation;
 import org.junit.Rule;
 
 import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryTest;
@@ -49,7 +50,7 @@ public class MemberOrderAnnotationFacetFactoryTest extends AbstractFacetFactoryT
         super.setUp();
 
         context.checking(new Expectations() {{
-            allowing(mockTranslationService).translate(with(any(String.class)), with(any(String.class)));
+            allowing(mockTranslationService).translate(with(any(TranslationContext.class)), with(any(String.class)));
             will(new Action() {
                 @Override
                 public Object invoke(final Invocation invocation) throws Throwable {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderComparatorTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderComparatorTest.java
index b1c9f87..056e08e 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderComparatorTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/ordering/memberorder/MemberOrderComparatorTest.java
@@ -25,6 +25,7 @@ import org.jmock.api.Action;
 import org.jmock.api.Invocation;
 import org.junit.Rule;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
@@ -59,6 +60,8 @@ public class MemberOrderComparatorTest extends TestCase {
     @Rule
     public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
 
+	static TranslationContext ctx = TranslationContext.ofSimpleStringIdentifier("test");
+    
     @Override
     protected void setUp() {
 
@@ -69,7 +72,7 @@ public class MemberOrderComparatorTest extends TestCase {
 
         mockTranslationService = context.mock(TranslationService.class);
         context.checking(new Expectations() {{
-            allowing(mockTranslationService).translate(with(any(String.class)), with(any(String.class)));
+            allowing(mockTranslationService).translate(with(any(TranslationContext.class)), with(any(String.class)));
             will(new Action() {
                 @Override
                 public Object invoke(final Invocation invocation) throws Throwable {
@@ -90,74 +93,74 @@ public class MemberOrderComparatorTest extends TestCase {
     }
 
     public void testDefaultGroupOneComponent() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, m2));
         assertEquals(-1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneComponentOtherWay() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "2", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "2", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, m2));
         assertEquals(+1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneComponentSame() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, m2));
         assertEquals(0, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsOutOfComponentsFirst() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1.1", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.1", mockTranslationService, m2));
         assertEquals(-1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsOutOfComponentsFirstOtherWay() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1.1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1", mockTranslationService, m2));
         assertEquals(+1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsTwoComponents() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1.1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2", mockTranslationService, m2));
         assertEquals(-1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsTwoComponentsOtherWay() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1.1", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.1", mockTranslationService, m2));
         assertEquals(+1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsLotsOfComponents() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.4", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2.5.8.3.3", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2.5.8.3.4", mockTranslationService, m2));
         assertEquals(-1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsLotsOfComponentsOtherWay() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.4", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2.5.8.3.4", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2.5.8.3.3", mockTranslationService, m2));
         assertEquals(+1, comparator.compare(m1, m2));
     }
 
     public void testDefaultGroupOneSideRunsLotsOfComponentsSame() {
-        m1.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("", "1.2.5.8.3.3", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2.5.8.3.3", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "", "1.2.5.8.3.3", mockTranslationService, m2));
         assertEquals(0, comparator.compare(m1, m2));
     }
 
     public void testNamedGroupOneSideRunsLotsOfComponents() {
-        m1.addFacet(new MemberOrderFacetAnnotation("abc", "1.2.5.8.3.3", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("abc", "1.2.5.8.3.4", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "abc", "1.2.5.8.3.3", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "abc", "1.2.5.8.3.4", mockTranslationService, m2));
         assertEquals(-1, comparator.compare(m1, m2));
     }
 
     public void testEnsuresInSameGroup() {
-        m1.addFacet(new MemberOrderFacetAnnotation("abc", "1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("def", "2", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "abc", "1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "def", "2", mockTranslationService, m2));
         try {
             assertEquals(-1, comparator.compare(m1, m2));
             fail("Exception should have been thrown");
@@ -167,14 +170,14 @@ public class MemberOrderComparatorTest extends TestCase {
     }
 
     public void testEnsuresInSameGroupCanBeDisabled() {
-        m1.addFacet(new MemberOrderFacetAnnotation("abc", "1", mockTranslationService, m1));
-        m2.addFacet(new MemberOrderFacetAnnotation("def", "2", mockTranslationService, m2));
+        m1.addFacet(new MemberOrderFacetAnnotation(ctx, "abc", "1", mockTranslationService, m1));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "def", "2", mockTranslationService, m2));
         assertEquals(-1, laxComparator.compare(m1, m2));
     }
 
     public void testNonAnnotatedAfterAnnotated() {
         // don't annotate m1
-        m2.addFacet(new MemberOrderFacetAnnotation("def", "2", mockTranslationService, m2));
+        m2.addFacet(new MemberOrderFacetAnnotation(ctx, "def", "2", mockTranslationService, m2));
         assertEquals(+1, comparator.compare(m1, m2));
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/Block.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/Block.java
index 2ca120e..758e6c3 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/Block.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/Block.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.internal.collections._Lists;
 
 class Block {
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoAbstract.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoAbstract.java
index 61bf8ca..d356394 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoAbstract.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoAbstract.java
@@ -19,6 +19,7 @@
 package org.apache.isis.core.runtimeservices.i18n.po;
 
 import org.apache.isis.applib.services.i18n.Mode;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 
 abstract class PoAbstract {
 
@@ -31,8 +32,8 @@ abstract class PoAbstract {
         this.mode = mode;
     }
 
-    abstract String translate(final String context, final String msgId);
-    abstract String translate(final String context, final String msgId, final String msgIdPlural, int num);
+    abstract String translate(final TranslationContext context, final String msgId);
+    abstract String translate(final TranslationContext context, final String msgId, final String msgIdPlural, int num);
 
     Mode getMode() {
         return mode;
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoDisabled.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoDisabled.java
index 8893c17..26d1415 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoDisabled.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoDisabled.java
@@ -19,6 +19,7 @@
 package org.apache.isis.core.runtimeservices.i18n.po;
 
 import org.apache.isis.applib.services.i18n.Mode;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 
 class PoDisabled extends PoAbstract {
 
@@ -27,12 +28,12 @@ class PoDisabled extends PoAbstract {
     }
 
     @Override
-    String translate(String context, String msgId) {
+    String translate(TranslationContext context, String msgId) {
         return msgId;
     }
 
     @Override
-    String translate(String context, String msgId, String msgIdPlural, int num) {
+    String translate(TranslationContext context, String msgId, String msgIdPlural, int num) {
         return msgId;
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoReader.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoReader.java
index 7f0133f..30b2f69 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoReader.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoReader.java
@@ -27,6 +27,7 @@ import java.util.stream.Collectors;
 
 import org.apache.isis.applib.services.i18n.LocaleProvider;
 import org.apache.isis.applib.services.i18n.Mode;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationsResolver;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
@@ -91,7 +92,7 @@ class PoReader extends PoAbstract {
     }
 
     @Override
-    public String translate(final String context, final String msgId) {
+    public String translate(TranslationContext context, final String msgId) {
         if(translationsResolver == null) {
             // already logged as WARN (in constructor) if null.
             return msgId;
@@ -100,7 +101,7 @@ class PoReader extends PoAbstract {
     }
 
     @Override
-    String translate(final String context, final String msgId, final String msgIdPlural, final int num) {
+    String translate(TranslationContext context, final String msgId, final String msgIdPlural, final int num) {
 
         final String msgIdToUse;
         final ContextAndMsgId.Type type;
@@ -121,8 +122,7 @@ class PoReader extends PoAbstract {
         init();
     }
 
-    private String translate(
-            final String context, final String msgId, final ContextAndMsgId.Type type) {
+    private String translate(TranslationContext context, final String msgId, final ContextAndMsgId.Type type) {
 
         final Locale targetLocale;
         try {
@@ -142,7 +142,7 @@ class PoReader extends PoAbstract {
         final Map<ContextAndMsgId, String> translationsByKey = readAndCacheTranslationsIfRequired(targetLocale);
 
         // search for translation with a context
-        final ContextAndMsgId key = new ContextAndMsgId(context, msgId, type);
+        final ContextAndMsgId key = new ContextAndMsgId(context.stringify(), msgId, type);
         final String translation = lookupTranslation(translationsByKey, key);
         if (!_Strings.isNullOrEmpty(translation)) {
             return translation;
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoWriter.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoWriter.java
index 0b149ce..7dbec6c 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoWriter.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/PoWriter.java
@@ -25,6 +25,7 @@ import java.util.SortedMap;
 import java.util.SortedSet;
 
 import org.apache.isis.applib.services.i18n.Mode;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Sets;
 
@@ -105,28 +106,28 @@ class PoWriter extends PoAbstract {
 
 
     @Override
-    public String translate(final String context, final String msgId) {
+    public String translate(final TranslationContext context, final String msgId) {
 
         if(msgId == null) {
             return null;
         }
         final Block block = blockFor(msgId);
         synchronized(block) {
-            block.contexts.add(context);
+            block.contexts.add(context.stringify());
         }
 
         return msgId;
     }
 
     @Override
-    String translate(final String context, final String msgId, final String msgIdPlural, final int num) {
+    String translate(final TranslationContext context, final String msgId, final String msgIdPlural, final int num) {
 
         if(msgId == null) {
             return null;
         }
         final Block block = blockFor(msgId);
         synchronized(block) {
-            block.contexts.add(context);
+            block.contexts.add(context.stringify());
             block.msgIdPlural = msgIdPlural;
         }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/TranslationServicePo.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/TranslationServicePo.java
index d293199..bdf4c36 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/TranslationServicePo.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/i18n/po/TranslationServicePo.java
@@ -33,6 +33,7 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.i18n.LocaleProvider;
 import org.apache.isis.applib.services.i18n.Mode;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.i18n.TranslationsResolver;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
@@ -104,12 +105,12 @@ public class TranslationServicePo implements TranslationService {
     }
 
     @Override
-    public String translate(final String context, final String text) {
+    public String translate(final TranslationContext context, final String text) {
         return po.translate(context, text);
     }
 
     @Override
-    public String translate(final String context, final String singularText, final String pluralText, final int num) {
+    public String translate(final TranslationContext context, final String singularText, final String pluralText, final int num) {
         return po.translate(context, singularText, pluralText, num);
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/message/MessageServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/message/MessageServiceDefault.java
index 6fdd82f..40f4173 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/message/MessageServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/message/MessageServiceDefault.java
@@ -33,6 +33,7 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.exceptions.RecoverableException;
 import org.apache.isis.applib.services.i18n.TranslatableString;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.core.interaction.session.MessageBroker;
@@ -66,7 +67,7 @@ public class MessageServiceDefault implements MessageService {
     @Override
     public String informUser(
             final TranslatableString message,
-            final String translationContext) {
+            final TranslationContext translationContext) {
         String translatedMessage = message.translate(translationService, translationContext);
         informUser(translatedMessage);
         return translatedMessage;
@@ -89,7 +90,7 @@ public class MessageServiceDefault implements MessageService {
     @Override
     public String warnUser(
             final TranslatableString message,
-            final String translationContext) {
+            final TranslationContext translationContext) {
         String translatedMessage = message.translate(translationService, translationContext);
         warnUser(translatedMessage);
         return translatedMessage;
@@ -111,14 +112,14 @@ public class MessageServiceDefault implements MessageService {
     @Override
     public String raiseError(
             final TranslatableString message,
-            final String translationContext) {
+            final TranslationContext translationContext) {
         final String translatedMessage = message.translate(translationService, translationContext);
         raiseError(translatedMessage);
         return translatedMessage;
     }
 
-    private static String context(final Class<?> contextClass, final String contextMethod) {
-        return contextClass.getName()+"#"+contextMethod;
+    private static TranslationContext context(final Class<?> contextClass, final String contextMethod) {
+        return TranslationContext.ofClassAndMethodName(contextClass, contextMethod);
     }
 
     private Optional<MessageBroker> currentMessageBroker() {
diff --git a/core/runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/i18n/po/PoReaderTest.java b/core/runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/i18n/po/PoReaderTest.java
index bcc5f47..46397fe 100644
--- a/core/runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/i18n/po/PoReaderTest.java
+++ b/core/runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/i18n/po/PoReaderTest.java
@@ -33,6 +33,7 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.services.i18n.LocaleProvider;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationsResolver;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -80,8 +81,8 @@ public class PoReaderTest {
         public void singleContext() throws Exception {
 
             // given
-            final String context =
-                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#object()";
+            final TranslationContext context = TranslationContext.ofSimpleStringIdentifier(
+                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#object()");
             final String msgId = "Work of art";
             final String msgStr = "Objet d'art";
 
@@ -89,7 +90,7 @@ public class PoReaderTest {
                 @Override
                 protected List<String> readPo(final Locale locale) {
                     final List<String> lines = _Lists.newArrayList();
-                    lines.add(String.format("#: %s", context));
+                    lines.add(String.format("#: %s", context.stringify()));
                     lines.add(String.format("msgid \"%s\"", msgId));
                     lines.add(String.format("msgstr \"%s\"", msgStr));
                     return lines;
@@ -107,10 +108,10 @@ public class PoReaderTest {
         public void multipleContext() throws Exception {
 
             // given
-            final String context1 =
-                    "fixture.simple.SimpleObjectsFixturesService#runFixtureScript(org.apache.isis.applib.fixturescripts.FixtureScript,java.lang.String)";
-            final String context2 =
-                    "org.apache.isis.applib.fixturescripts.FixtureScripts#runFixtureScript(org.apache.isis.applib.fixturescripts.FixtureScript,java.lang.String)";
+            final TranslationContext context1 = TranslationContext.ofSimpleStringIdentifier(
+                    "fixture.simple.SimpleObjectsFixturesService#runFixtureScript(org.apache.isis.applib.fixturescripts.FixtureScript,java.lang.String)");
+            final TranslationContext context2 = TranslationContext.ofSimpleStringIdentifier(
+                    "org.apache.isis.applib.fixturescripts.FixtureScripts#runFixtureScript(org.apache.isis.applib.fixturescripts.FixtureScript,java.lang.String)");
             final String msgId = "Parameters";
             final String msgStr = "Paramètres";
 
@@ -118,8 +119,8 @@ public class PoReaderTest {
                 @Override
                 protected List<String> readPo(final Locale locale) {
                     final List<String> lines = _Lists.newArrayList();
-                    lines.add(String.format("#: %s", context1));
-                    lines.add(String.format("#: %s", context2));
+                    lines.add(String.format("#: %s", context1.stringify()));
+                    lines.add(String.format("#: %s", context2.stringify()));
                     lines.add(String.format("msgid \"%s\"", msgId));
                     lines.add(String.format("msgstr \"%s\"", msgStr));
                     return lines;
@@ -142,13 +143,13 @@ public class PoReaderTest {
         public void multipleBlocks() throws Exception {
 
             // given
-            final String context1 =
-                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#object()";
+            final TranslationContext context1 = TranslationContext.ofSimpleStringIdentifier(
+                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#object()");
             final String msgid1 = "Work of art";
             final String msgstr1 = "Objet d'art";
 
-            final String context2 =
-                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#lookup()";
+            final TranslationContext context2 = TranslationContext.ofSimpleStringIdentifier(
+                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#lookup()");
             final String msgid2 = "Lookup";
             final String msgstr2 = "Look up";
 
@@ -156,14 +157,14 @@ public class PoReaderTest {
                 @Override
                 protected List<String> readPo(final Locale locale) {
                     final List<String> lines = _Lists.newArrayList();
-                    lines.add(String.format("#: %s", context1));
+                    lines.add(String.format("#: %s", context1.stringify()));
                     lines.add(String.format("msgid \"%s\"", msgid1));
                     lines.add(String.format("msgstr \"%s\"", msgstr1));
 
                     lines.add(String.format(""));
                     lines.add(String.format("# "));
 
-                    lines.add(String.format("#: %s", context2));
+                    lines.add(String.format("#: %s", context2.stringify()));
                     lines.add(String.format("msgid \"%s\"", msgid2));
                     lines.add(String.format("msgstr \"%s\"", msgstr2));
 
@@ -189,8 +190,8 @@ public class PoReaderTest {
         public void withPlurals() throws Exception {
 
             // given
-            final String context =
-                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#object()";
+            final TranslationContext context = TranslationContext.ofSimpleStringIdentifier(
+                    "org.apache.isis.applib.services.bookmark.BookmarkHolderAssociationContributions#object()");
             final String msgid = "Work of art";
             final String msgid_plural = "Works of art";
             final String msgstr$0 = "Œuvre d'art";
@@ -200,7 +201,7 @@ public class PoReaderTest {
                 @Override
                 protected List<String> readPo(final Locale locale) {
                     final List<String> lines = _Lists.newArrayList();
-                    lines.add(String.format("#: %s", context));
+                    lines.add(String.format("#: %s", context.stringify()));
                     lines.add(String.format("msgid \"%s\"", msgid));
                     lines.add(String.format("msgid_plural \"%s\"", msgid_plural));
                     lines.add(String.format("msgstr[0] \"%s\"", msgstr$0));
@@ -235,9 +236,11 @@ public class PoReaderTest {
                     return _Lists.newArrayList();
                 }
             };
+            
+            TranslationContext context = TranslationContext.ofSimpleStringIdentifier("someContext");
 
             // when
-            final String translated = poReader.translate("someContext", "Something to translate");
+            final String translated = poReader.translate(context, "Something to translate");
 
             // then
             assertThat(translated, is(equalTo("Something to translate")));
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/decorator/confirm/ConfirmUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/decorator/confirm/ConfirmUiModel.java
index 0816bca..aad71b1 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/decorator/confirm/ConfirmUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/decorator/confirm/ConfirmUiModel.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.common.model.decorator.confirm;
 import java.io.Serializable;
 import java.util.Optional;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.core.config.messages.MessageRegistry;
 
@@ -47,9 +48,11 @@ public class ConfirmUiModel implements Serializable {
     
     public static ConfirmUiModel ofAreYouSure(TranslationService translationService, Placement placement) {
         
-        val areYouSure = translate(translationService, MessageRegistry.MSG_ARE_YOU_SURE); 
-        val confirm = translate(translationService, MessageRegistry.MSG_CONFIRM);
-        val cancel = translate(translationService, MessageRegistry.MSG_CANCEL);
+    	TranslationContext context = TranslationContext.ofClass(MessageRegistry.class);
+    	
+        val areYouSure = translate(translationService, context, MessageRegistry.MSG_ARE_YOU_SURE); 
+        val confirm = translate(translationService, context, MessageRegistry.MSG_CONFIRM);
+        val cancel = translate(translationService, context, MessageRegistry.MSG_CANCEL);
         
         val message = Optional.<String>empty(); // not used yet
         
@@ -58,9 +61,9 @@ public class ConfirmUiModel implements Serializable {
     
     // -- HELPER
     
-    private static String translate(TranslationService translationService, String msg) {
-        if(translationService!=null) {
-            return translationService.translate(MessageRegistry.class.getName(), msg);
+    private static String translate(TranslationService translationService, TranslationContext context, String msg) {
+        if(translationService!=null) {        	
+            return translationService.translate(context, msg);
         }
         return msg;
     }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java
index fd1f8e9..74a74f3 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/tabs/TabGroupPanel.java
@@ -30,6 +30,7 @@ import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.layout.grid.bootstrap3.BS3Tab;
 import org.apache.isis.applib.layout.grid.bootstrap3.BS3TabGroup;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.util.ComponentHintKey;
@@ -64,7 +65,10 @@ implements HasDynamicallyVisibleContent {
 
         for (val bs3Tab : tablist) {
             final RepeatingViewWithDynamicallyVisibleContent rv = TabPanel.newRows(entityModel, bs3Tab);
-            String translateContext = entityModel.getTypeOfSpecification().getFullIdentifier();
+            
+            TranslationContext translateContext = TranslationContext.ofIdentifierForTab(entityModel.getTypeOfSpecification().getIdentifier());
+            // String translateContext = entityModel.getTypeOfSpecification().getFullIdentifier();
+            
             String bs3TabName = bs3Tab.getName();
             String tabName = translationService.translate(translateContext, bs3TabName);
             tabs.add(new AbstractTab(Model.of(tabName)) {
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/LocalizerForIsis.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/LocalizerForIsis.java
index 3993fc7..42e01c7 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/LocalizerForIsis.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/LocalizerForIsis.java
@@ -32,6 +32,7 @@ import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.base._Strings;
@@ -74,7 +75,7 @@ public class LocalizerForIsis extends Localizer {
 
     protected String translate(final String key, final Component component) {
         final Class<?> contextClass = determineContextClassElse(component, IsisWicketApplication.class);
-        final String context = contextClass.getName();
+        final TranslationContext context = TranslationContext.ofClass(contextClass);
         if(isisInteractionTracker.isInInteraction()) {
             return translate(key, context);
         } else {
@@ -141,7 +142,7 @@ public class LocalizerForIsis extends Localizer {
         return enclosingClass != null? enclosing(enclosingClass): cls;
     }
 
-    private String translate(final String key, final String context) {
+    private String translate(final String key, final TranslationContext context) {
         return translationService.translate(context, key);
     }
 
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java
index 74ccb04..c02f25c 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java
@@ -50,6 +50,7 @@ import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerService;
 import org.apache.isis.applib.services.exceprecog.Recognition;
+import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
@@ -357,7 +358,9 @@ public class WebRequestCycleForIsis implements IRequestCycleListener {
             return null;
         }
         return getCommonContext().getTranslationService()
-                .translate(WebRequestCycleForIsis.class.getName(), text);
+                .translate(
+                		TranslationContext.ofClass(WebRequestCycleForIsis.class), 
+                		text);
     }
 
     protected PageProvider errorPageProviderFor(Exception ex) {