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/13 09:18:21 UTC

[isis] branch master updated: ISIS-2604: further simplify mm validation

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


The following commit(s) were added to refs/heads/master by this push:
     new 471c63b  ISIS-2604: further simplify mm validation
471c63b is described below

commit 471c63b5c38b262c4f74d0b636d6e4aa2f4d08dd
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Apr 13 11:18:08 2021 +0200

    ISIS-2604: further simplify mm validation
    
    also prepare removal of DeficiencyFacet
---
 .../action/ActionAnnotationFacetFactory.java       |  15 +--
 .../actions/layout/ActionLayoutFacetFactory.java   |  14 +--
 .../facets/all/deficiencies/DeficiencyFacet.java   | 104 +++------------------
 .../CollectionAnnotationFacetFactory.java          |  16 +---
 .../layout/CollectionLayoutFacetFactory.java       |  18 +---
 .../ViewModelSemanticCheckingFacetFactory.java     |  16 +---
 .../DomainObjectAnnotationFacetFactory.java        |  13 ---
 .../mixin/MetaModelValidatorForMixinTypes.java     |   4 +-
 .../parameter/ParameterAnnotationFacetFactory.java |  19 +---
 .../property/PropertyAnnotationFacetFactory.java   |  28 +-----
 .../propertylayout/PropertyLayoutFacetFactory.java |  16 +---
 .../title/TitlesAndTranslationsValidator.java      |  41 ++++----
 .../metamodel/specloader/SpecificationLoader.java  |   3 +
 .../specloader/SpecificationLoaderDefault.java     |  22 ++++-
 .../specloader/validator/MetaModelValidator.java   |  27 ++----
 .../validator/MetaModelValidatorAbstract.java      |  42 ++++-----
 ...ModelValidatorForAmbiguousMixinAnnotations.java |   8 +-
 ...etaModelValidatorForConflictingOptionality.java |  16 +++-
 .../MetaModelValidatorForDeprecatedAbstract.java   |  68 --------------
 .../MetaModelValidatorForDeprecatedAnnotation.java |  54 -----------
 ...etaModelValidatorForDeprecatedMethodPrefix.java |  52 -----------
 .../MetaModelValidatorForValidationFailures.java   |  23 -----
 .../validator/MetaModelValidatorVisiting.java      |   3 +-
 .../specloader/validator/ValidationFailures.java   |   4 +
 .../ViewModelSemanticCheckingFacetFactoryTest.java |  47 +++++-----
 ...AnnotationFacetFactoryTest_refineMetaModel.java |  99 ++++++++++----------
 26 files changed, 200 insertions(+), 572 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
index 0950722..0e580ae 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
@@ -55,13 +55,8 @@ import org.apache.isis.core.metamodel.util.EventUtil;
 import lombok.val;
 
 public class ActionAnnotationFacetFactory
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
+extends FacetFactoryAbstract {
 
-    private final MetaModelValidatorForAmbiguousMixinAnnotations ambiguousMixinAnnotationsValidator
-            = new MetaModelValidatorForAmbiguousMixinAnnotations();
-
-    
     public ActionAnnotationFacetFactory() {
         super(FeatureType.ACTIONS_ONLY);
     }
@@ -72,7 +67,7 @@ implements MetaModelRefiner {
         val actionIfAny = processMethodContext
                 .synthesizeOnMethodOrMixinType(
                         Action.class, 
-                        () -> ambiguousMixinAnnotationsValidator
+                        () -> MetaModelValidatorForAmbiguousMixinAnnotations
                         .addValidationFailure(processMethodContext.getFacetHolder(), Action.class));
 
         processExplicit(processMethodContext, actionIfAny);
@@ -298,11 +293,5 @@ implements MetaModelRefiner {
         super.addFacet(facet);
     }
 
-    // -- METAMODEL REFINER
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(ambiguousMixinAnnotationsValidator);
-    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/layout/ActionLayoutFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/layout/ActionLayoutFacetFactory.java
index 1b38452..d6900ba 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/layout/ActionLayoutFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/layout/ActionLayoutFacetFactory.java
@@ -43,12 +43,8 @@ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorFor
 import lombok.val;
 
 public class ActionLayoutFacetFactory 
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
+extends FacetFactoryAbstract {
     
-    private final MetaModelValidatorForAmbiguousMixinAnnotations ambiguousMixinAnnotationsValidator
-            = new MetaModelValidatorForAmbiguousMixinAnnotations();
-
     public ActionLayoutFacetFactory() {
         super(FeatureType.ACTIONS_ONLY);
     }
@@ -60,7 +56,7 @@ implements MetaModelRefiner {
         val actionLayoutIfAny = processMethodContext
                 .synthesizeOnMethodOrMixinType(
                         ActionLayout.class,
-                        () -> ambiguousMixinAnnotationsValidator
+                        () -> MetaModelValidatorForAmbiguousMixinAnnotations
                         .addValidationFailure(processMethodContext.getFacetHolder(), ActionLayout.class));
         
         // bookmarkable
@@ -119,11 +115,5 @@ implements MetaModelRefiner {
 
     }
 
-    // -- METAMODEL REFINER
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(ambiguousMixinAnnotationsValidator);
-    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/deficiencies/DeficiencyFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/deficiencies/DeficiencyFacet.java
index e5ec7fc..71114ef 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/deficiencies/DeficiencyFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/deficiencies/DeficiencyFacet.java
@@ -19,135 +19,55 @@
 
 package org.apache.isis.core.metamodel.facets.all.deficiencies;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
+import org.apache.isis.core.metamodel.specloader.validator.ValidationFailure;
 
-import static org.apache.isis.commons.internal.base._With.computeIfAbsent;
-
-import lombok.Getter;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
 import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import lombok.Value;
 import lombok.val;
 
 /**
  * Collects meta-model validation failures (deficiencies) directly with the holder that is involved.
  * @since 2.0
  */
-@RequiredArgsConstructor(staticName = "of")
-public final class DeficiencyFacet implements Facet {
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class DeficiencyFacet {
 
-    @NonNull @Getter private final FacetHolder facetHolder;
-    @NonNull @Getter private final List<Deficiency> deficiencies;
-    
-    @Value(staticConstructor = "of")
-    public static final class Deficiency {
-        @NonNull @Getter private Identifier deficiencyOrigin;
-        @NonNull @Getter private String deficiencyMessage;
-    }
-    
     /**
      * Create a new DeficiencyFacet for the facetHolder (if it not already has one), 
      * then adds given deficiency information to the facet. 
      */
-    public static DeficiencyFacet appendTo(
+    public static void appendTo(
             @NonNull FacetHolder facetHolder, 
             @NonNull Identifier deficiencyOrigin, 
             @NonNull String deficiencyMessage) {
         
-        val deficiencyFacet = computeIfAbsent(facetHolder.getFacet(DeficiencyFacet.class), 
-                ()->DeficiencyFacet.of(facetHolder, new ArrayList<>()));
-        
-        deficiencyFacet.getDeficiencies().add(Deficiency.of(deficiencyOrigin, deficiencyMessage));
-        return deficiencyFacet;
+        val validationFailure = ValidationFailure.of(deficiencyOrigin, deficiencyMessage);
+        facetHolder.getSpecificationLoader().addValidationFailure(validationFailure);
     }
     
     /**
      * Create a new DeficiencyFacet for the facetHolder (if it not already has one), 
      * then adds given deficiency information to the facet. 
      */
-    public static DeficiencyFacet appendTo(
+    public static void appendTo(
             @NonNull IdentifiedHolder facetHolder, 
             @NonNull String deficiencyMessage) {
-        return appendTo(facetHolder, facetHolder.getIdentifier(), deficiencyMessage);
+        appendTo(facetHolder, facetHolder.getIdentifier(), deficiencyMessage);
     }
     
     /**
      * Create a new DeficiencyFacet for the facetHolder (if it not already has one), 
      * then adds given deficiency information to the facet. 
      */
-    public static DeficiencyFacet appendToWithFormat(
+    public static void appendToWithFormat(
             @NonNull IdentifiedHolder facetHolder, 
             @NonNull String messageFormat, 
             final Object ...args) {
-        return appendTo(facetHolder, String.format(messageFormat, args));
-    }
-
-    
-    // -- FACET IMPLEMENTATION
-    
-    @Override
-    public void setFacetHolder(FacetHolder facetHolder) {
-        throw _Exceptions.unsupportedOperation();
-    }
-
-    @Override
-    public Facet getUnderlyingFacet() {
-        return null;
-    }
-
-    @Override
-    public void setUnderlyingFacet(Facet underlyingFacet) {
-        throw _Exceptions.unsupportedOperation();
-    }
-
-    @Override
-    public Class<? extends Facet> facetType() {
-        return DeficiencyFacet.class;
+        appendTo(facetHolder, String.format(messageFormat, args));
     }
 
-    @Override
-    public boolean isDerived() {
-        return false;
-    }
-
-    @Override
-    public boolean isFallback() {
-        return true;
-    }
-
-    @Override
-    public boolean alwaysReplace() {
-        return false;
-    }
-
-    @Override
-    public void appendAttributesTo(Map<String, Object> attributeMap) {
-        throw _Exceptions.unsupportedOperation();
-    }
-
-    @Override
-    public void addContributedFacet(Facet contributedFacet) {
-        throw _Exceptions.unsupportedOperation();
-    }
-
-    @Override
-    public void forEachContributedFacet(Consumer<Facet> onContributedFacet) {
-        throw _Exceptions.unsupportedOperation();
-    }
-
-    @Override
-    public Class<? extends Facet> facetAliasType() {
-        return null;
-    }
-
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
index dfc31f1..d55c680 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
@@ -30,7 +30,6 @@ import org.apache.isis.applib.events.domain.CollectionDomainEvent;
 import org.apache.isis.commons.internal.collections._Collections;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacetInferredFromArray;
@@ -45,7 +44,6 @@ import org.apache.isis.core.metamodel.facets.collections.collection.modify.Colle
 import org.apache.isis.core.metamodel.facets.collections.collection.typeof.TypeOfFacetOnCollectionFromCollectionAnnotation;
 import org.apache.isis.core.metamodel.facets.object.domainobject.domainevents.CollectionDomainEventDefaultFacetForDomainObjectAnnotation;
 import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForAmbiguousMixinAnnotations;
 import org.apache.isis.core.metamodel.util.EventUtil;
@@ -53,12 +51,8 @@ import org.apache.isis.core.metamodel.util.EventUtil;
 import lombok.val;
 
 public class CollectionAnnotationFacetFactory
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
+extends FacetFactoryAbstract {
     
-    private final MetaModelValidatorForAmbiguousMixinAnnotations ambiguousMixinAnnotationsValidator
-        = new MetaModelValidatorForAmbiguousMixinAnnotations();
-
     public CollectionAnnotationFacetFactory() {
         super(FeatureType.COLLECTIONS_AND_ACTIONS);
     }
@@ -69,7 +63,7 @@ implements MetaModelRefiner {
         val collectionIfAny = processMethodContext
                 .synthesizeOnMethodOrMixinType(
                         Collection.class, 
-                        () -> ambiguousMixinAnnotationsValidator
+                        () -> MetaModelValidatorForAmbiguousMixinAnnotations
                         .addValidationFailure(processMethodContext.getFacetHolder(), Collection.class));
 
         inferIntentWhenOnTypeLevel(processMethodContext, collectionIfAny);
@@ -227,12 +221,6 @@ implements MetaModelRefiner {
         return null;
     }
 
-    // -- METAMODEL REFINER
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(ambiguousMixinAnnotationsValidator);
-    }
 
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
index fba354c..8c30877 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
@@ -20,21 +20,15 @@ package org.apache.isis.core.metamodel.facets.collections.layout;
 
 import org.apache.isis.applib.annotation.CollectionLayout;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.members.layout.order.LayoutOrderFacetFromCollectionLayoutAnnotation;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForAmbiguousMixinAnnotations;
 
 import lombok.val;
 
 public class CollectionLayoutFacetFactory 
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
+extends FacetFactoryAbstract {
 
-    private final MetaModelValidatorForAmbiguousMixinAnnotations ambiguousMixinAnnotationsValidator
-        = new MetaModelValidatorForAmbiguousMixinAnnotations();
-    
     public CollectionLayoutFacetFactory() {
         super(FeatureType.COLLECTIONS_AND_ACTIONS);
     }
@@ -46,7 +40,7 @@ implements MetaModelRefiner {
         val collectionLayoutIfAny = processMethodContext
                 .synthesizeOnMethodOrMixinType(
                         CollectionLayout.class, 
-                        () -> ambiguousMixinAnnotationsValidator
+                        () -> MetaModelValidatorForAmbiguousMixinAnnotations
                         .addValidationFailure(processMethodContext.getFacetHolder(), CollectionLayout.class));
 
         val cssClassFacet = CssClassFacetForCollectionLayoutAnnotation
@@ -82,12 +76,4 @@ implements MetaModelRefiner {
         super.addFacet(sortedByFacet);
     }
 
-    // -- METAMODEL REFINER
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(ambiguousMixinAnnotationsValidator);
-    }
-
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
index f8a7169..ae34683 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
@@ -26,31 +26,22 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.facets.Annotations;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
 
 import lombok.val;
 
 public class ViewModelSemanticCheckingFacetFactory 
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
-
+extends FacetFactoryAbstract {
 
     public ViewModelSemanticCheckingFacetFactory() {
         super(FeatureType.OBJECTS_ONLY);
     }
 
-    private final MetaModelValidatorForValidationFailures validator = 
-            new MetaModelValidatorForValidationFailures();
-
     @Override
     public void setMetaModelContext(MetaModelContext metaModelContext) {
         super.setMetaModelContext(metaModelContext);
-        validator.setMetaModelContext(metaModelContext);
     }
     
     @Override
@@ -134,10 +125,5 @@ implements MetaModelRefiner {
 
     }
 
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(validator);
-    }
-
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 22d2805..b2d4e17 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -76,8 +76,6 @@ import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacetForDomainObj
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting;
 import org.apache.isis.core.metamodel.util.EventUtil;
 
@@ -89,14 +87,9 @@ import lombok.val;
 public class DomainObjectAnnotationFacetFactory extends FacetFactoryAbstract
 implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory {
 
-    private final MetaModelValidatorForValidationFailures autoCompleteMethodInvalid =
-            new MetaModelValidatorForValidationFailures();
-
     private final MetaModelValidatorForMixinTypes mixinTypeValidator =
             new MetaModelValidatorForMixinTypes("@DomainObject#nature=MIXIN");
 
-
-
     public DomainObjectAnnotationFacetFactory() {
         super(FeatureType.OBJECTS_ONLY);
     }
@@ -104,8 +97,6 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
     @Override
     public void setMetaModelContext(MetaModelContext metaModelContext) {
         super.setMetaModelContext(metaModelContext);
-        autoCompleteMethodInvalid.setMetaModelContext(metaModelContext);
-        mixinTypeValidator.setMetaModelContext(metaModelContext);
     }
 
     @Override
@@ -483,13 +474,9 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
 
     @Override
     public void refineProgrammingModel(ProgrammingModel programmingModel) {
-
         if(getConfiguration().getCore().getMetaModel().getValidator().isEnsureUniqueObjectTypes()) {
             addValidatorToEnsureUniqueLogicalTypeNames(programmingModel);
         }
-
-        programmingModel.addValidator(autoCompleteMethodInvalid);
-        programmingModel.addValidator(mixinTypeValidator);
     }
 
     private void addValidatorToEnsureUniqueLogicalTypeNames(ProgrammingModel pm) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
index 73533b5..9eccf74 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
@@ -23,15 +23,13 @@ import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.reflection._Reflect;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorAbstract;
 
 import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramCount;
 
 import lombok.NonNull;
 import lombok.val;
 
-public class MetaModelValidatorForMixinTypes 
-extends MetaModelValidatorAbstract {
+public class MetaModelValidatorForMixinTypes {
 
     private final String annotation;
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
index e60cf95..f573a16 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
@@ -25,7 +25,6 @@ import javax.validation.constraints.Pattern;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
 import org.apache.isis.core.metamodel.facets.param.parameter.fileaccept.FileAcceptFacetForParameterAnnotation;
@@ -35,16 +34,12 @@ import org.apache.isis.core.metamodel.facets.param.parameter.maxlen.MaxLengthFac
 import org.apache.isis.core.metamodel.facets.param.parameter.mustsatisfy.MustSatisfySpecificationFacetForParameterAnnotation;
 import org.apache.isis.core.metamodel.facets.param.parameter.regex.RegExFacetForParameterAnnotation;
 import org.apache.isis.core.metamodel.facets.param.parameter.regex.RegExFacetForPatternAnnotationOnParameter;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForConflictingOptionality;
 
 import lombok.val;
 
-public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract
-implements MetaModelRefiner {
-
-    private final MetaModelValidatorForConflictingOptionality conflictingOptionalityValidator = 
-            new MetaModelValidatorForConflictingOptionality();
+public class ParameterAnnotationFacetFactory 
+extends FacetFactoryAbstract {
 
     public ParameterAnnotationFacetFactory() {
         super(FeatureType.PARAMETERS_ONLY);
@@ -53,7 +48,6 @@ implements MetaModelRefiner {
     @Override
     public void setMetaModelContext(MetaModelContext metaModelContext) {
         super.setMetaModelContext(metaModelContext);
-        conflictingOptionalityValidator.setMetaModelContext(metaModelContext);
     }
 
     @Override
@@ -105,14 +99,14 @@ implements MetaModelRefiner {
         final MandatoryFacet facet =
                 MandatoryFacetInvertedByNullableAnnotationOnParameter.create(nullableIfAny, parameterType, holder);
         super.addFacet(facet);
-        conflictingOptionalityValidator.flagIfConflict(
+        MetaModelValidatorForConflictingOptionality.flagIfConflict(
                 facet, "Conflicting @Nullable with other optionality annotation");
 
         val parameterIfAny = processParameterContext.synthesizeOnParameter(Parameter.class);
         final MandatoryFacet mandatoryFacet =
                 MandatoryFacetForParameterAnnotation.create(parameterIfAny, parameterType, holder);
         super.addFacet(mandatoryFacet);
-        conflictingOptionalityValidator.flagIfConflict(
+        MetaModelValidatorForConflictingOptionality.flagIfConflict(
                 mandatoryFacet, "Conflicting @Parameter#optionality with other optionality annotation");
 
     }
@@ -125,10 +119,5 @@ implements MetaModelRefiner {
         super.addFacet(FileAcceptFacetForParameterAnnotation.create(parameterIfAny, holder));
     }
 
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(conflictingOptionalityValidator);
-    }
-
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
index c2a9579..549208d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
@@ -31,7 +31,6 @@ import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.actions.contributing.ContributingFacet.Contributing;
 import org.apache.isis.core.metamodel.facets.actions.contributing.ContributingFacetAbstract;
@@ -60,7 +59,6 @@ import org.apache.isis.core.metamodel.facets.properties.property.regex.RegExFace
 import org.apache.isis.core.metamodel.facets.properties.property.regex.RegExFacetForPropertyAnnotation;
 import org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyClearFacet;
 import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForAmbiguousMixinAnnotations;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForConflictingOptionality;
@@ -69,14 +67,7 @@ import org.apache.isis.core.metamodel.util.EventUtil;
 import lombok.val;
 
 public class PropertyAnnotationFacetFactory 
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
-
-    private final MetaModelValidatorForConflictingOptionality conflictingOptionalityValidator 
-        = new MetaModelValidatorForConflictingOptionality();
-    
-    private final MetaModelValidatorForAmbiguousMixinAnnotations ambiguousMixinAnnotationsValidator
-        = new MetaModelValidatorForAmbiguousMixinAnnotations();
+extends FacetFactoryAbstract {
 
     public PropertyAnnotationFacetFactory() {
         super(FeatureType.PROPERTIES_AND_ACTIONS);
@@ -85,7 +76,6 @@ implements MetaModelRefiner {
     @Override
     public void setMetaModelContext(MetaModelContext metaModelContext) {
         super.setMetaModelContext(metaModelContext);
-        conflictingOptionalityValidator.setMetaModelContext(metaModelContext);
     }
 
     @Override
@@ -94,7 +84,7 @@ implements MetaModelRefiner {
         val propertyIfAny = processMethodContext
                 .synthesizeOnMethodOrMixinType(
                         Property.class, 
-                        () -> ambiguousMixinAnnotationsValidator
+                        () -> MetaModelValidatorForAmbiguousMixinAnnotations
                             .addValidationFailure(processMethodContext.getFacetHolder(), Property.class));
 
         inferIntentWhenOnTypeLevel(processMethodContext, propertyIfAny);
@@ -339,13 +329,13 @@ implements MetaModelRefiner {
         val facet2 =
                 MandatoryFacetInvertedByNullableAnnotationOnProperty.create(nullableIfAny, method, holder);
         super.addFacet(facet2);
-        conflictingOptionalityValidator.flagIfConflict(
+        MetaModelValidatorForConflictingOptionality.flagIfConflict(
                 facet2, "Conflicting @Nullable with other optionality annotation");
 
         // search for @Property(optional=...)
         val facet3 = MandatoryFacetForPropertyAnnotation.create(propertyIfAny, method, holder);
         super.addFacet(facet3);
-        conflictingOptionalityValidator.flagIfConflict(
+        MetaModelValidatorForConflictingOptionality.flagIfConflict(
                 facet3, "Conflicting Property#optionality with other optionality annotation");
     }
 
@@ -369,7 +359,6 @@ implements MetaModelRefiner {
 
     }
 
-
     void processFileAccept(final ProcessMethodContext processMethodContext, Optional<Property> propertyIfAny) {
         val holder = processMethodContext.getFacetHolder();
 
@@ -379,13 +368,4 @@ implements MetaModelRefiner {
         super.addFacet(facet);
     }
 
-    // -- METAMODEL REFINER
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(conflictingOptionalityValidator);
-        programmingModel.addValidator(ambiguousMixinAnnotationsValidator);
-    }
-
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/PropertyLayoutFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/PropertyLayoutFacetFactory.java
index 1706647..c6e1dfb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/PropertyLayoutFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/PropertyLayoutFacetFactory.java
@@ -21,22 +21,16 @@ package org.apache.isis.core.metamodel.facets.properties.propertylayout;
 
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.facets.members.layout.group.LayoutGroupFacetFromPropertyLayoutAnnotation;
 import org.apache.isis.core.metamodel.facets.members.layout.order.LayoutOrderFacetFromPropertyLayoutAnnotation;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForAmbiguousMixinAnnotations;
 
 import lombok.val;
 
 public class PropertyLayoutFacetFactory 
-extends FacetFactoryAbstract
-implements MetaModelRefiner {
+extends FacetFactoryAbstract {
     
-    private final MetaModelValidatorForAmbiguousMixinAnnotations ambiguousMixinAnnotationsValidator
-        = new MetaModelValidatorForAmbiguousMixinAnnotations();
-
     public PropertyLayoutFacetFactory() {
         super(FeatureType.PROPERTIES_AND_ACTIONS);
     }
@@ -48,7 +42,7 @@ implements MetaModelRefiner {
         val propertyLayoutIfAny = processMethodContext
                 .synthesizeOnMethodOrMixinType(
                         PropertyLayout.class, 
-                        () -> ambiguousMixinAnnotationsValidator
+                        () -> MetaModelValidatorForAmbiguousMixinAnnotations
                         .addValidationFailure(processMethodContext.getFacetHolder(), PropertyLayout.class));
 
         val cssClassFacet = CssClassFacetForPropertyLayoutAnnotation
@@ -101,11 +95,5 @@ implements MetaModelRefiner {
         
     }
     
-    // -- METAMODEL REFINER
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel) {
-        programmingModel.addValidator(ambiguousMixinAnnotationsValidator);
-    }
 
 }
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 0f055d6..8944b56 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
@@ -24,10 +24,9 @@ import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.title.TitleService;
 import org.apache.isis.commons.internal.base._Blackhole;
 import org.apache.isis.core.config.messages.MessageRegistry;
+import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorAbstract;
-import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 
-import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -38,13 +37,10 @@ import lombok.val;
 public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
 
     @Override
-    public void collectFailuresInto(@NonNull ValidationFailures validationFailures) {
-        
+    public void validate() {
         validateServiceTitles();
         validateEnumTitles();
         validateRegisteredMessageTranslation();
-        
-        super.collectFailuresInto(validationFailures);
     }
 
     private void validateServiceTitles() {
@@ -67,11 +63,13 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
                         LogicalType.eager(managedBeanAdapter.getBeanClass(), objectType));
                 val facetHolder = specificationLoader.loadSpecification(managedBeanAdapter.getBeanClass());
                 
-                super.onFailure(
+                DeficiencyFacet.appendTo(
                         facetHolder, 
                         deficiencyOrigin, 
-                        "Failed to get instance of service bean %s", 
-                        managedBeanAdapter.getId());
+                        String.format(
+                                "Failed to get instance of service bean %s", 
+                                managedBeanAdapter.getId())
+                        );
                 return; // next
             }
 
@@ -88,11 +86,13 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
                         LogicalType.eager(managedBeanAdapter.getBeanClass(), objectType));
                 val facetHolder = specificationLoader.loadSpecification(managedBeanAdapter.getBeanClass());
 
-                super.onFailure(
+                DeficiencyFacet.appendTo(
                         facetHolder, 
                         deficiencyOrigin, 
-                        "Failed to get title for service bean %s", 
-                        managedBeanAdapter.getId());
+                        String.format(
+                                "Failed to get title for service bean %s", 
+                                managedBeanAdapter.getId())
+                        );
             }
 
 
@@ -124,11 +124,13 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
                         val deficiencyOrigin = Identifier.classIdentifier(objSpec.getLogicalType());
                         val facetHolder = objSpec;
 
-                        super.onFailure(
+                        DeficiencyFacet.appendTo(
                                 facetHolder, 
                                 deficiencyOrigin, 
-                                "Failed to get title for enum constant %s", 
-                                "" + enumConstant);
+                                String.format(
+                                        "Failed to get title for enum constant %s", 
+                                        "" + enumConstant)
+                                );
                     }
 
                 }
@@ -160,15 +162,18 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
                 val spec = specificationLoader.loadSpecification(MessageRegistry.class);
                 val deficiencyOrigin = Identifier.classIdentifier(spec.getLogicalType());
 
-                super.onFailure(
+                DeficiencyFacet.appendTo(
                         spec, 
                         deficiencyOrigin, 
-                        "Failed to translate message %s from MessageRegistry", 
-                        "" + message);
+                        String.format(
+                                "Failed to translate message %s from MessageRegistry", 
+                                "" + message)
+                        );
             }
 
         }
 
     }
 
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index 04c08bc..be9e5f1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@ -33,6 +33,7 @@ import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
+import org.apache.isis.core.metamodel.specloader.validator.ValidationFailure;
 import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 
 import static org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED;
@@ -65,6 +66,8 @@ public interface SpecificationLoader {
      * others are only triggered when calling this method. 
      */
     ValidationFailures getValidationResult();
+    
+    void addValidationFailure(ValidationFailure validationFailure);
 
     // -- LOOKUP
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
index 32d156f..53e436d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -72,6 +72,7 @@ import org.apache.isis.core.metamodel.specloader.postprocessor.PostProcessor;
 import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
 import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorAbstract;
+import org.apache.isis.core.metamodel.specloader.validator.ValidationFailure;
 import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 import org.apache.isis.core.metamodel.valuetypes.ValueTypeProviderDefault;
 import org.apache.isis.core.metamodel.valuetypes.ValueTypeRegistry;
@@ -463,6 +464,19 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
     
     // -- VALIDATION STUFF
     
+    private final ValidationFailures validationFailures = new ValidationFailures();
+    
+    @Override
+    public void addValidationFailure(ValidationFailure validationFailure) {
+        if(validationResult.isMemoized()) {
+            throw _Exceptions.illegalState(
+                    "Validation result was already created and can no longer be modified.");
+        }
+        synchronized(validationFailures) {
+            validationFailures.add(validationFailure);;
+        }
+    }
+    
     private _Lazy<ValidationFailures> validationResult = 
             _Lazy.threadSafe(this::collectFailuresFromMetaModel);
 
@@ -471,13 +485,13 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
     
     private ValidationFailures collectFailuresFromMetaModel() {
         validationInProgress.set(true);               
-        val failures = new ValidationFailures();
+        
         programmingModel.streamValidators()
         .map(MetaModelValidatorAbstract.class::cast)
         .forEach(validator -> {
             log.debug("Running validator: {}", validator);
             try {
-                validator.collectFailuresInto(failures);
+                validator.validate();
             } catch (Throwable t) {
                 log.error(t);
                 throw t;
@@ -485,9 +499,11 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
                 log.debug("Done validator: {}", validator);
             }
         });
+        
         log.debug("Done");
         validationInProgress.set(false);
-        return failures;
+        
+        return validationFailures;
     }
 
     // -- HELPER
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidator.java
index 3d995f5..a507865 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidator.java
@@ -19,23 +19,16 @@
 
 package org.apache.isis.core.metamodel.specloader.validator;
 
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
-
-import lombok.NonNull;
-import lombok.val;
-
 public interface MetaModelValidator {
 
-    default void onFailure(
-            @NonNull FacetHolder facetHolder,
-            @NonNull Identifier deficiencyOrigin,
-            @NonNull String deficiencyMessageFormat,
-            Object ...args) {
-        
-        val deficiencyMessage = String.format(deficiencyMessageFormat, args);
-        
-        DeficiencyFacet.appendTo(facetHolder, deficiencyOrigin, deficiencyMessage);
-    }
+    /**
+     * Collect any {@link ValidationFailure} to given validationFailures. 
+     *  
+     * @param validationFailures
+     */
+    //void collectFailuresInto(@NonNull ValidationFailures validationFailures);
+    
+    void validate();
+    
+    
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
index fef705e..8bf3c81 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
@@ -19,15 +19,11 @@
 
 package org.apache.isis.core.metamodel.specloader.validator;
 
-import org.apache.isis.applib.Identifier;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.context.MetaModelContextAware;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
 
 import lombok.Getter;
-import lombok.NonNull;
 import lombok.Setter;
 
 public abstract class MetaModelValidatorAbstract 
@@ -35,30 +31,30 @@ implements
     MetaModelValidator, 
     MetaModelContextAware {
 
-    protected final ValidationFailures failures = new ValidationFailures();
+    //protected final ValidationFailures failures = new ValidationFailures();
     
     @Getter @Setter(onMethod = @__(@Override))
     private MetaModelContext metaModelContext;
     
-    /**
-     * Collect any {@link ValidationFailure} to given validationFailures. 
-     *  
-     * @param validationFailures
-     */
-    public void collectFailuresInto(@NonNull ValidationFailures validationFailures) {
-        validationFailures.addAll(failures);
-    }
+//    /**
+//     * Collect any {@link ValidationFailure} to given validationFailures. 
+//     *  
+//     * @param validationFailures
+//     */
+//    @Override
+//    public void collectFailuresInto(@NonNull ValidationFailures validationFailures) {
+//        validationFailures.addAll(failures);
+//    }
 
-    @Override
-    public void onFailure(
-            @NonNull FacetHolder facetHolder, 
-            @NonNull Identifier deficiencyOrigin,
-            @NonNull String deficiencyMessageFormat, 
-            Object... args) {
-        
-        DeficiencyFacet.appendTo(facetHolder, deficiencyOrigin, String.format(deficiencyMessageFormat, args));
-        failures.add(deficiencyOrigin, deficiencyMessageFormat, args);
-    }
+//    public void onFailure(
+//            @NonNull FacetHolder facetHolder, 
+//            @NonNull Identifier deficiencyOrigin,
+//            @NonNull String deficiencyMessageFormat, 
+//            Object... args) {
+//        
+//        DeficiencyFacet.appendTo(facetHolder, deficiencyOrigin, String.format(deficiencyMessageFormat, args));
+//        failures.add(deficiencyOrigin, deficiencyMessageFormat, args);
+//    }
     
     protected IsisConfiguration getConfiguration() {
         return metaModelContext.getConfiguration();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForAmbiguousMixinAnnotations.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForAmbiguousMixinAnnotations.java
index b2de637..1de1dd6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForAmbiguousMixinAnnotations.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForAmbiguousMixinAnnotations.java
@@ -23,10 +23,12 @@ import java.lang.annotation.Annotation;
 import org.apache.isis.core.metamodel.facets.FacetedMethod;
 import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
 
-public class MetaModelValidatorForAmbiguousMixinAnnotations 
-extends MetaModelValidatorAbstract {
+import lombok.experimental.UtilityClass;
 
-    public <A extends Annotation> void addValidationFailure(
+@UtilityClass
+public class MetaModelValidatorForAmbiguousMixinAnnotations {
+
+    public static <A extends Annotation> void addValidationFailure(
             final FacetedMethod holder,
             final Class<A> annotationType) {
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
index 35d0604..f83211b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
@@ -20,14 +20,17 @@ package org.apache.isis.core.metamodel.specloader.validator;
 
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
+import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacetDefault;
 
 import lombok.val;
+import lombok.experimental.UtilityClass;
 
-public class MetaModelValidatorForConflictingOptionality extends MetaModelValidatorAbstract {
+@UtilityClass
+public class MetaModelValidatorForConflictingOptionality {
 
-    public Facet flagIfConflict(final MandatoryFacet facet, final String message) {
+    public static Facet flagIfConflict(final MandatoryFacet facet, final String message) {
         if(conflictingOptionality(facet)) {
             addFailure(facet, message);
         }
@@ -36,11 +39,14 @@ public class MetaModelValidatorForConflictingOptionality extends MetaModelValida
     
     // -- HELPER
 
-    private Facet addFailure(final Facet facet, final String message) {
+    private static Facet addFailure(final Facet facet, final String message) {
         if(facet != null) {
             val holder = (IdentifiedHolder) facet.getFacetHolder();
-            val identifier = holder.getIdentifier();
-            super.onFailure(holder, identifier, "%s : %s", message, identifier.getFullIdentityString());
+            DeficiencyFacet.appendToWithFormat(
+                    holder, 
+                    "%s : %s", 
+                    message, 
+                    holder.getIdentifier().getFullIdentityString());
         }
         return facet;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java
deleted file mode 100644
index d82489a..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.validator;
-
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
-import org.apache.isis.core.metamodel.facets.FacetFactory;
-
-import lombok.val;
-
-@Deprecated //not used any more?
-abstract class MetaModelValidatorForDeprecatedAbstract extends MetaModelValidatorAbstract {
-
-    /**
-     * @param facet
-     */
-    public <T extends Facet> T flagIfPresent(T facet) {
-        return flagIfPresent(facet, null);
-    }
-
-    /**
-     * @param facet
-     * @param processMethodContext - can be null if none available.
-     */
-    public <T extends Facet> T flagIfPresent(T facet, FacetFactory.AbstractProcessWithMethodContext<?> processMethodContext) {
-        if(facet != null && 
-                !getConfiguration().getCore().getMetaModel().getValidator().isAllowDeprecated()) {
-            
-            val holder = (IdentifiedHolder) facet.getFacetHolder();
-            val identifier = holder.getIdentifier();
-            super.onFailure(holder, identifier, failureMessageFor(facet, processMethodContext));
-        }
-        return facet;
-    }
-
-    /**
-     * Convenience for subclasses.
-     */
-    static boolean isInherited(FacetFactory.AbstractProcessWithMethodContext<?> processContext) {
-        if (processContext == null) {
-            return false;
-        }
-        final Class<?> introspectedCls = processContext.getCls();
-        final Class<?> declaringClass = processContext.getMethod().getDeclaringClass();
-        return introspectedCls != declaringClass;
-    }
-
-    protected abstract String failureMessageFor(Facet facet, FacetFactory.AbstractProcessWithMethodContext<?> processMethodContext);
-
-  
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAnnotation.java
deleted file mode 100644
index 56a1f8f..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAnnotation.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.validator;
-
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
-import org.apache.isis.core.metamodel.facets.FacetFactory;
-
-@Deprecated //not used any more?
-class MetaModelValidatorForDeprecatedAnnotation extends MetaModelValidatorForDeprecatedAbstract{
-
-    private String annotationName;
-
-    public MetaModelValidatorForDeprecatedAnnotation(final Class<?> annotationType) {
-        annotationName = annotationType.getSimpleName();
-    }
-
-    @Override
-    protected String failureMessageFor(
-            final Facet facet,
-            final FacetFactory.AbstractProcessWithMethodContext<?> processContext) {
-
-        final boolean inherited = isInherited(processContext);
-
-        final IdentifiedHolder facetHolder = (IdentifiedHolder) facet.getFacetHolder();
-        final Identifier identifier = facetHolder.getIdentifier();
-        final String id = identifier.getFullIdentityString();
-        return String.format(
-                "%s%s: annotation '%s' is deprecated",
-                id,
-                (inherited?" (inherited)":""),
-                annotationName);
-    }
-
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java
deleted file mode 100644
index 7b3a9aa..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.validator;
-
-import org.apache.isis.applib.Identifier;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
-import org.apache.isis.core.metamodel.facets.FacetFactory;
-
-@Deprecated //not used any more?
-class MetaModelValidatorForDeprecatedMethodPrefix extends MetaModelValidatorForDeprecatedAbstract {
-
-    private final String methodPrefix;
-
-    public MetaModelValidatorForDeprecatedMethodPrefix(final String methodPrefix) {
-        this.methodPrefix = methodPrefix;
-    }
-
-    @Override
-    protected String failureMessageFor(
-            final Facet facet, 
-            final FacetFactory.AbstractProcessWithMethodContext<?> processMethodContext) {
-
-        final boolean inherited = isInherited(processMethodContext);
-
-        final IdentifiedHolder identifiedHolder = (IdentifiedHolder) facet.getFacetHolder();
-        final Identifier identifier = identifiedHolder.getIdentifier();
-        final String id = identifier.getFullIdentityString();
-        return String.format(
-                "%s%s: method prefix '%s' is deprecated",
-                id,
-                (inherited?" (inherited)":""),
-                methodPrefix);
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java
deleted file mode 100644
index 9e803f5..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.specloader.validator;
-
-public class MetaModelValidatorForValidationFailures extends MetaModelValidatorAbstract {
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorVisiting.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorVisiting.java
index 97394c0..411aafa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorVisiting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorVisiting.java
@@ -72,10 +72,9 @@ extends MetaModelValidatorAbstract {
     }
 
     @Override
-    public void collectFailuresInto(@NonNull ValidationFailures validationFailures) {
+    public void validate() {
         validateAll();
         summarize();
-        super.collectFailuresInto(validationFailures);
     }
 
     private void validateAll() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/ValidationFailures.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/ValidationFailures.java
index b2c5943..d4129e4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/ValidationFailures.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/ValidationFailures.java
@@ -47,6 +47,10 @@ public final class ValidationFailures implements Iterable<ValidationFailure> {
         }
     }
 
+    public void add(ValidationFailure validationFailure) {
+        failures.add(validationFailure);
+    }
+    
     public void add(ValidationFailures validationFailures) {
         addAll(validationFailures.getFailures());
     }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
index fdc9829e..1a9ed7e 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
@@ -39,7 +39,6 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelInitFilterDefault;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorAbstract;
 import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 
 import lombok.val;
@@ -55,33 +54,20 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
 
     private MetaModelContext metaModelContext;
     private ViewModelSemanticCheckingFacetFactory facetFactory;
-
-    private ValidationFailures processThenValidate(final Class<?> cls) {
-        
-        val programmingModel = new ProgrammingModelAbstract(mockServicesInjector) {};
-        facetFactory.refineProgrammingModel(programmingModel);
-        programmingModel.init(new ProgrammingModelInitFilterDefault(), metaModelContext);
-        
-        val holder = new FacetHolderImpl();
-        ((MetaModelContextAware)holder).setMetaModelContext(metaModelContext);
-        facetFactory.process(new FacetFactory.ProcessClassContext(cls, null, holder));
-        
-        val validationFailures = new ValidationFailures();
-        
-        programmingModel.streamValidators()
-        .forEach(validator->((MetaModelValidatorAbstract)validator).collectFailuresInto(validationFailures));
-
-        return validationFailures;
-    }
+    private ProgrammingModelAbstract programmingModel;
 
     @Before
     public void setUp() throws Exception {
 
         val configuration = new IsisConfiguration(null);
         configuration.getApplib().getAnnotation().getViewModel().getValidation().getSemanticChecking().setEnable(true);
+        
+        programmingModel = new ProgrammingModelAbstract(mockServicesInjector) {};
+        programmingModel.init(new ProgrammingModelInitFilterDefault(), metaModelContext);
 
         metaModelContext = MetaModelContext_forTesting.builder()
                 .configuration(configuration)
+                .programmingModel(programmingModel)
                 .build();
 
         facetFactory = new ViewModelSemanticCheckingFacetFactory();
@@ -96,7 +82,7 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
         class ValidAnnotatedDomainObjectAndDomainObjectLayout {
         }
 
-        final ValidationFailures validationFailures = processThenValidate(ValidAnnotatedDomainObjectAndDomainObjectLayout.class);
+        val validationFailures = processThenValidate(ValidAnnotatedDomainObjectAndDomainObjectLayout.class);
         assertThat(validationFailures.getNumberOfFailures(), is(0));
     }
 
@@ -114,7 +100,8 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
             }
         }
 
-        final ValidationFailures validationFailures = processThenValidate(ValidDomainObjectWithViewModelNatureImplementingRecreatableDomainObject.class);
+        val validationFailures = processThenValidate(
+                ValidDomainObjectWithViewModelNatureImplementingRecreatableDomainObject.class);
         assertThat(validationFailures.getNumberOfFailures(), is(0));
     }
 
@@ -132,8 +119,8 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
             }
         }
 
-        final ValidationFailures validationFailures = 
-                processThenValidate(InvalidDomainObjectWithNatureNotSpecifiedImplementingRecreatableDomainObject.class);
+        val validationFailures = processThenValidate(
+                InvalidDomainObjectWithNatureNotSpecifiedImplementingRecreatableDomainObject.class);
         assertThat(validationFailures.getNumberOfFailures(), is(1));
         assertThat(validationFailures.getMessages().iterator().next(), containsString("should not be annotated with @DomainObject with nature of NOT_SPECIFIED and also implement RecreatableDomainObject (specify a nature of VIEW_MODEL)"));
     }
@@ -152,13 +139,23 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
             }
         }
 
-        final ValidationFailures validationFailures = 
-                processThenValidate(InvalidDomainObjectWithNatureJdoEntityImplementingRecreatableDomainObject.class);
+        val validationFailures = processThenValidate(
+                InvalidDomainObjectWithNatureJdoEntityImplementingRecreatableDomainObject.class);
         assertThat(validationFailures.getNumberOfFailures(), is(1));
         assertThat(validationFailures.getMessages().iterator().next(), 
                 containsString("should not be annotated with @DomainObject with nature of ENTITY and also implement RecreatableDomainObject (specify a nature of VIEW_MODEL)"));
     }
 
+    // -- HELPER
+    
+    private ValidationFailures processThenValidate(final Class<?> cls) {
+        
+        val holder = new FacetHolderImpl();
+        ((MetaModelContextAware)holder).setMetaModelContext(metaModelContext);
+        facetFactory.process(new FacetFactory.ProcessClassContext(cls, null, holder));
+        
+        return metaModelContext.getSpecificationLoader().getValidationResult();
+    }
 
 
 }
\ No newline at end of file
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
index e75ff44..efb6099 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
@@ -30,15 +30,16 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.services.inject.ServiceInjector;
+import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.core.metamodel._testing.MetaModelContext_forTesting;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.all.deficiencies.DeficiencyFacet;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelInitFilterDefault;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorAbstract;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 import org.apache.isis.persistence.jdo.metamodel.testing.AbstractFacetFactoryTest;
 
 import lombok.val;
@@ -51,9 +52,10 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
     private ObjectSpecification mockChildType;
     private ObjectSpecification mockParentType;
     private ObjectSpecification mockGrandParentType;
+    private ServiceInjector mockServicesInjector;
 
     private Visitor newValidatorVisitor;
-    private MetaModelValidator validator;
+    private MetaModelContext metaModelContext;
 
     private Sequence sequence;
 
@@ -63,22 +65,22 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
         mockParentType = context.mock(ObjectSpecification.class, "mockParenttype");
         mockGrandParentType = context.mock(ObjectSpecification.class, "mockGrandParenttype");
 
-        val mockMetaModelContext = context.mock(MetaModelContext.class, "mockMetaModelContext");
-        
-        sequence = context.sequence("inorder");
+        val configuration = new IsisConfiguration(null);
 
-        validator = new MetaModelValidatorAbstract() {
-            {
-                setMetaModelContext(mockMetaModelContext);
-            }
-        };
+        val programmingModel = new ProgrammingModelAbstract(mockServicesInjector) {};
+        programmingModel.init(new ProgrammingModelInitFilterDefault(), metaModelContext);
         
+        metaModelContext = MetaModelContext_forTesting.builder()
+                .configuration(configuration)
+                .programmingModel(programmingModel)
+                .build();
+
+        sequence = context.sequence("inorder");
         
         val facetFactory = new JdoVersionAnnotationFacetFactory();
         facetFactory.setJdoFacetContext(AbstractFacetFactoryTest.jdoFacetContextForTesting());
         
         newValidatorVisitor = facetFactory.newValidatorVisitor();
-                
     }
 
     @Test
@@ -95,9 +97,7 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
 
         newValidatorVisitor.visit(mockChildType);
         
-        val failures = new ValidationFailures();
-        ((MetaModelValidatorAbstract)validator).collectFailuresInto(failures);
-        
+        val failures = metaModelContext.getSpecificationLoader().getValidationResult();
         assertThat(failures.getNumberOfFailures(), is(0));
     }
 
@@ -121,9 +121,7 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
 
         newValidatorVisitor.visit(mockChildType);
 
-        val failures = new ValidationFailures();
-        ((MetaModelValidatorAbstract)validator).collectFailuresInto(failures);
-        
+        val failures = metaModelContext.getSpecificationLoader().getValidationResult();
         assertThat(failures.getNumberOfFailures(), is(0));
     }
 
@@ -157,9 +155,7 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
 
         newValidatorVisitor.visit(mockChildType);
 
-        val failures = new ValidationFailures();
-        ((MetaModelValidatorAbstract)validator).collectFailuresInto(failures);
-        
+        val failures = metaModelContext.getSpecificationLoader().getValidationResult();
         assertThat(failures.getNumberOfFailures(), is(0));
     }
 
@@ -175,41 +171,44 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
 
         context.checking(new Expectations() {
             {
-                oneOf(mockChildType).getCorrespondingClass();
+                allowing(mockChildType).getCorrespondingClass();
                 inSequence(sequence);
                 will(returnValue(Child.class));
 
-                oneOf(mockChildType).superclass();
+                allowing(mockChildType).superclass();
                 inSequence(sequence);
                 will(returnValue(mockParentType));
 
-                oneOf(mockParentType).getCorrespondingClass();
+                allowing(mockParentType).getCorrespondingClass();
                 inSequence(sequence);
                 will(returnValue(Parent.class));
                 
-                oneOf(mockChildType).getIdentifier();
+                allowing(mockChildType).getIdentifier();
                 inSequence(sequence);
                 will(returnValue(Identifier.classIdentifier(TypeIdentifierTestFactory.customer())));
 
-                oneOf(mockChildType).getFullIdentifier();
+                allowing(mockChildType).getFullIdentifier();
                 inSequence(sequence);
                 will(returnValue("mockChildType"));
 
-                oneOf(mockParentType).getFullIdentifier();
+                allowing(mockParentType).getFullIdentifier();
                 inSequence(sequence);
                 will(returnValue("mockParentType"));
                 
-                oneOf(mockChildType).getFacet(DeficiencyFacet.class);
-                will(returnValue(null));
-
-
+                allowing(mockParentType).getSpecificationLoader();
+                inSequence(sequence);
+                will(returnValue(metaModelContext.getSpecificationLoader()));
+                
+                allowing(mockChildType).getSpecificationLoader();
+                inSequence(sequence);
+                will(returnValue(metaModelContext.getSpecificationLoader()));
+                
             }
         });
 
         newValidatorVisitor.visit(mockChildType);
 
-        val failures = new ValidationFailures();
-        ((MetaModelValidatorAbstract)validator).collectFailuresInto(failures);
+        val failures = metaModelContext.getSpecificationLoader().getValidationResult();
         
         assertThat(failures.getNumberOfFailures(), is(1));
         assertThat(failures.getMessages().iterator().next(), is("mockChildType: cannot have @Version annotated on this subclass and any of its supertypes; superclass: mockParentType"));
@@ -230,48 +229,52 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
 
         context.checking(new Expectations() {
             {
-                oneOf(mockChildType).getCorrespondingClass();
+                allowing(mockChildType).getCorrespondingClass();
                 inSequence(sequence);
                 will(returnValue(Child.class));
 
-                oneOf(mockChildType).superclass();
+                allowing(mockChildType).superclass();
                 inSequence(sequence);
                 will(returnValue(mockParentType));
 
-                oneOf(mockParentType).getCorrespondingClass();
+                allowing(mockParentType).getCorrespondingClass();
                 inSequence(sequence);
                 will(returnValue(Parent.class));
 
-                oneOf(mockParentType).superclass();
+                allowing(mockParentType).superclass();
                 inSequence(sequence);
                 will(returnValue(mockGrandParentType));
 
-                oneOf(mockGrandParentType).getCorrespondingClass();
+                allowing(mockGrandParentType).getCorrespondingClass();
                 inSequence(sequence);
                 will(returnValue(GrandParent.class));
                 
-                oneOf(mockChildType).getIdentifier();
+                allowing(mockChildType).getIdentifier();
                 inSequence(sequence);
                 will(returnValue(Identifier.classIdentifier(TypeIdentifierTestFactory.customer())));
 
-                oneOf(mockChildType).getFullIdentifier();
+                allowing(mockChildType).getFullIdentifier();
                 inSequence(sequence);
                 will(returnValue("mockChildType"));
 
-                oneOf(mockGrandParentType).getFullIdentifier();
+                allowing(mockGrandParentType).getFullIdentifier();
                 inSequence(sequence);
                 will(returnValue("mockGrandParentType"));
                 
-                oneOf(mockChildType).getFacet(DeficiencyFacet.class);
-                will(returnValue(null));
-
+                allowing(mockParentType).getSpecificationLoader();
+                inSequence(sequence);
+                will(returnValue(metaModelContext.getSpecificationLoader()));
+                
+                allowing(mockChildType).getSpecificationLoader();
+                inSequence(sequence);
+                will(returnValue(metaModelContext.getSpecificationLoader()));
+                
             }
         });
 
         newValidatorVisitor.visit(mockChildType);
 
-        val failures = new ValidationFailures();
-        ((MetaModelValidatorAbstract)validator).collectFailuresInto(failures);
+        val failures = metaModelContext.getSpecificationLoader().getValidationResult();
         
         assertThat(failures.getNumberOfFailures(), is(1));
         assertThat(failures.getMessages().iterator().next(), is("mockChildType: cannot have @Version annotated on this subclass and any of its supertypes; superclass: mockGrandParentType"));