POLYGENE-265 - method argument names are now used in Constraint Violations.
POLYGENE-264 - Consolidated how the ConstraintViolationException works.
POLYGENE-262 - NoSuchCompositeException and subtypes changed name to 
NoSuchCompositeTypeException.


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/559b38a5
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/559b38a5
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/559b38a5

Branch: refs/heads/develop
Commit: 559b38a5b0c857c6553ae9dff925ff71a65f1cae
Parents: 85a37fd
Author: niclas <nic...@hedhman.org>
Authored: Mon Jun 19 15:43:59 2017 +0800
Committer: niclas <nic...@hedhman.org>
Committed: Mon Jun 19 15:43:59 2017 +0800

----------------------------------------------------------------------
 .../api/composite/NoSuchCompositeException.java |  56 ----
 .../composite/NoSuchCompositeTypeException.java | 138 ++++++++
 .../api/composite/NoSuchTransientException.java |  45 ---
 .../composite/NoSuchTransientTypeException.java |  42 +++
 .../api/composite/TransientBuilderFactory.java  |   8 +-
 .../api/constraint/ConstraintViolation.java     |  56 ----
 .../ConstraintViolationException.java           | 312 +++++++++++--------
 .../constraint/ValueConstraintViolation.java    |  79 +++++
 .../api/object/NoSuchObjectException.java       |  57 ----
 .../api/object/NoSuchObjectTypeException.java   |  57 ++++
 .../polygene/api/object/ObjectFactory.java      |   4 +-
 .../api/service/NoSuchServiceException.java     |  58 ----
 .../api/service/NoSuchServiceTypeException.java |  47 +++
 .../polygene/api/service/ServiceFinder.java     |   8 +-
 .../unitofwork/NoSuchEntityTypeException.java   |  21 +-
 .../polygene/api/unitofwork/UnitOfWork.java     |   2 -
 .../api/value/NoSuchValueException.java         |  46 ---
 .../api/value/NoSuchValueTypeException.java     |  45 +++
 .../polygene/api/value/ValueBuilderFactory.java |  14 +-
 .../bootstrap/AssemblyReportException.java      |   5 +-
 .../association/AbstractAssociationModel.java   |  10 +-
 .../bootstrap/CompositeAssemblyImpl.java        | 117 ++++---
 .../runtime/bootstrap/ModuleAssemblyImpl.java   |   2 +-
 .../runtime/composite/CompositeModel.java       |  11 +-
 .../runtime/composite/ConstraintsInstance.java  |  24 +-
 .../composite/FragmentInvocationHandler.java    |  15 +-
 .../composite/ValueConstraintsInstance.java     |  33 +-
 .../composite/ValueConstraintsModel.java        |  14 +-
 .../polygene/runtime/entity/EntityInstance.java |  13 +-
 .../ServiceInjectionProviderFactory.java        |   4 +-
 .../provider/UsesInjectionProviderFactory.java  |   8 +-
 .../runtime/property/PropertyModel.java         |   9 +-
 .../runtime/query/QueryBuilderFactoryImpl.java  |   4 +-
 .../runtime/structure/ModuleInstance.java       |  46 +--
 .../runtime/value/ValueBuilderInstance.java     |   4 +-
 .../polygene/runtime/value/ValueModel.java      | 114 ++++++-
 .../constraints/PropertyConstraintTest.java     |   4 +-
 .../composite/CompositeFactoryImplTest.java     |   4 +-
 .../composite/InterfaceDefaultMethodsTest.java  |   7 +-
 .../runtime/constraints/ConstraintsTest.java    |   6 +-
 .../objects/ObjectBuilderFactoryTest.java       |   4 +-
 .../runtime/objects/ObjectVisibilityTest.java   |  62 ++--
 .../runtime/service/ServiceVisibilityTest.java  |  62 ++--
 .../runtime/structure/MixinVisibilityTest.java  |   4 +-
 .../PrivateCompositeVisibilityTest.java         |   4 +-
 .../transients/TransientBuilderFactoryTest.java |   4 +-
 .../transients/TransientVisibilityTest.java     |  62 ++--
 .../runtime/value/ValueVisibilityTest.java      |  62 ++--
 .../test/cache/AbstractCachePoolTest.java       |  11 +-
 .../test/entity/model/EntityStoreTestSuite.java | 153 +++++++--
 .../test/entity/model/legal/LegalService.java   |  68 +++-
 .../polygene/test/entity/model/legal/Will.java  |  14 +-
 .../test/entity/model/legal/WillAmount.java     |   3 +-
 .../test/entity/model/legal/WillBenefit.java    |   1 +
 .../test/entity/model/monetary/Currency.java    |  51 +++
 .../polygene/test/entity/model/people/Rent.java |  20 +-
 .../polygene/test/cache/MemoryCacheTest.java    |   3 +-
 .../apache/polygene/test/docker/DockerRule.java |   2 +-
 .../library/constraints/ConstraintTest.java     |   3 +-
 .../rest/server/api/ContextResource.java        |   4 +-
 .../restlet/ConstraintViolationMessages.java    |   4 +-
 .../restlet/InteractionConstraintsService.java  |   6 +-
 .../ParameterViolationConcern.java              |   4 +-
 .../PhoneNumberParameterViolationConcern.java   |   6 +-
 64 files changed, 1294 insertions(+), 872 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
deleted file mode 100644
index c3f51bb..0000000
--- 
a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
+++ /dev/null
@@ -1,56 +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.polygene.api.composite;
-
-import org.apache.polygene.api.common.InvalidApplicationException;
-
-/**
- * This exception is thrown if client code tries to create a non-existing 
Composite type.
- */
-public class NoSuchCompositeException extends InvalidApplicationException
-{
-    private final String compositeType;
-    private final String moduleName;
-    private final String visibleTypes;
-
-    protected NoSuchCompositeException( String metaType, String compositeType, 
String moduleName, String visibleTypes )
-    {
-        super( "Could not find any visible " + metaType + " of type [" + 
compositeType + "] in module [" +
-               moduleName + "].\n" + visibleTypes );
-        this.compositeType = compositeType;
-        this.moduleName = moduleName;
-        this.visibleTypes = visibleTypes;
-    }
-
-    public String compositeType()
-    {
-        return compositeType;
-    }
-
-    public String moduleName()
-    {
-        return moduleName;
-    }
-
-    public String visibleTypes()
-    {
-        return visibleTypes;
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeTypeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeTypeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeTypeException.java
new file mode 100644
index 0000000..64977ef
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeTypeException.java
@@ -0,0 +1,138 @@
+/*
+ *  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.polygene.api.composite;
+
+import java.util.stream.Stream;
+import org.apache.polygene.api.common.InvalidApplicationException;
+import org.apache.polygene.api.structure.TypeLookup;
+
+import static java.util.stream.Collectors.joining;
+
+/**
+ * This exception is thrown if client code tries to create a non-existing 
Composite type.
+ */
+public abstract class NoSuchCompositeTypeException extends 
InvalidApplicationException
+{
+    private final String compositeType;
+    private final String moduleName;
+    private final String visibleTypes;
+    private final String metaType;
+    private final String candidateTypes;
+
+    protected NoSuchCompositeTypeException( String metaType, String 
compositeType, String moduleName, TypeLookup typeLookup )
+    {
+        super( "\n\tCould not find any visible " + metaType + " of type [" + 
compositeType + "] in module [" + moduleName + "]." );
+        this.metaType = metaType;
+        this.compositeType = compositeType;
+        this.moduleName = moduleName;
+        visibleTypes = formatVisibleTypes( typeLookup );
+        candidateTypes = findCandidateTypes( typeLookup );
+    }
+
+    public String compositeType()
+    {
+        return compositeType;
+    }
+
+    public String moduleName()
+    {
+        return moduleName;
+    }
+
+    public String visibleTypes()
+    {
+        return visibleTypes;
+    }
+
+    public String candidateTypes()
+    {
+        return candidateTypes;
+    }
+
+    @Override
+    public String getMessage()
+    {
+        return super.getMessage() + "\n" + candidateTypes + "\n" + 
visibleTypes;
+    }
+
+    private String formatVisibleTypes( TypeLookup typeLookup )
+    {
+        return descriptors( typeLookup )
+            .map( descriptor ->
+                  {
+                      String moduleName = descriptor.module().name();
+                      String typeName = descriptor.primaryType().getName();
+                      return "\t\t[" + typeName + "] in [" + moduleName + "]";
+                  } )
+            .sorted()
+            .distinct()
+            .collect( joining( "\n", "\tVisible " + metaType + " types 
are:\n", "" ) );
+    }
+
+    private String findCandidateTypes( TypeLookup typeLookup )
+    {
+        return "";
+//        return descriptors( typeLookup )
+//            .filter( type -> compositeType.equals( 
type.primaryType().getName() ) )
+//            .map( descriptor ->
+//                  {
+//                      Class<?> primarytype = descriptor.primaryType();
+//                      String typeName = primarytype.getName();
+//                      return "\t\t[ " + typeName + "] in [" + 
descriptor.module().name() + "] with visibility " + descriptor.visibility();
+//                  } )
+//            .collect( joining( "\n", "\tInvisible " + metaType + " types 
are:\n", "" ) );
+    }
+
+    protected abstract Stream<? extends CompositeDescriptor> descriptors( 
TypeLookup typeLookup );
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if( this == o )
+        {
+            return true;
+        }
+        if( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        NoSuchCompositeTypeException that = (NoSuchCompositeTypeException) o;
+
+        if( !compositeType.equals( that.compositeType ) )
+        {
+            return false;
+        }
+        if( !moduleName.equals( that.moduleName ) )
+        {
+            return false;
+        }
+        return visibleTypes.equals( that.visibleTypes );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = compositeType.hashCode();
+        result = 31 * result + moduleName.hashCode();
+        result = 31 * result + visibleTypes.hashCode();
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
 
b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
deleted file mode 100644
index d55c34d..0000000
--- 
a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
+++ /dev/null
@@ -1,45 +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.polygene.api.composite;
-
-import org.apache.polygene.api.structure.TypeLookup;
-
-import static java.util.stream.Collectors.joining;
-
-/**
- * This exception is thrown if client code tries to create a non-existing 
TransientComposite type.
- */
-public class NoSuchTransientException extends NoSuchCompositeException
-{
-    public NoSuchTransientException( String typeName, String moduleName, 
TypeLookup typeLookup )
-    {
-        super( "TransientComposite", typeName, moduleName, formatVisibleTypes( 
typeLookup ) );
-    }
-
-    private static String formatVisibleTypes( TypeLookup typeLookup )
-    {
-        return typeLookup.allTransients()
-                         .map( descriptor -> 
descriptor.primaryType().getName() )
-                         .sorted()
-                         .distinct()
-                         .collect( joining( "\n", "Visible transient types 
are:\n", "" ) );
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientTypeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientTypeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientTypeException.java
new file mode 100644
index 0000000..45ecd17
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientTypeException.java
@@ -0,0 +1,42 @@
+/*
+ *  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.polygene.api.composite;
+
+import java.util.stream.Stream;
+import org.apache.polygene.api.structure.TypeLookup;
+
+import static java.util.stream.Collectors.joining;
+
+/**
+ * This exception is thrown if client code tries to create a non-existing 
TransientComposite type.
+ */
+public class NoSuchTransientTypeException extends NoSuchCompositeTypeException
+{
+    public NoSuchTransientTypeException( String typeName, String moduleName, 
TypeLookup typeLookup )
+    {
+        super( "TransientComposite", typeName, moduleName, typeLookup );
+    }
+
+    protected Stream<? extends CompositeDescriptor> descriptors( TypeLookup 
typeLookup )
+    {
+        return typeLookup.allTransients();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
 
b/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
index 5656c71..12f71e9 100644
--- 
a/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
+++ 
b/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
@@ -39,10 +39,10 @@ public interface TransientBuilderFactory
      *
      * @return a TransientBuilder for creation of TransientComposites 
implementing the interface
      *
-     * @throws NoSuchTransientException if no composite extending the 
mixinType has been registered
+     * @throws NoSuchTransientTypeException if no composite extending the 
mixinType has been registered
      */
     <T> TransientBuilder<T> newTransientBuilder( Class<T> mixinType )
-        throws NoSuchTransientException;
+        throws NoSuchTransientTypeException;
 
     /**
      * Instantiate a TransientComposite of the given type.
@@ -53,10 +53,10 @@ public interface TransientBuilderFactory
      *
      * @return a new TransientComposite instance
      *
-     * @throws NoSuchTransientException if no composite extending the 
mixinType has been registered
+     * @throws NoSuchTransientTypeException if no composite extending the 
mixinType has been registered
      * @throws org.apache.polygene.api.common.ConstructionException
      *                                  if the composite could not be 
instantiated
      */
     <T> T newTransient( Class<T> mixinType, Object... uses )
-        throws NoSuchTransientException, ConstructionException;
+        throws NoSuchTransientTypeException, ConstructionException;
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolation.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolation.java
 
b/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolation.java
deleted file mode 100644
index 75bbecb..0000000
--- 
a/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolation.java
+++ /dev/null
@@ -1,56 +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.polygene.api.constraint;
-
-import java.lang.annotation.Annotation;
-
-/**
- * When a constraint violation has occurred (ie Constraint.isValid has 
returned false) it
- * is put in a collection of all violations that have occurred for this value 
check.
- */
-public final class ConstraintViolation
-{
-    private String name;
-    private final Annotation constraint;
-    private final Object value;
-
-    public ConstraintViolation( String name, Annotation constraint, Object 
value )
-    {
-        this.name = name;
-        this.constraint = constraint;
-        this.value = value;
-    }
-
-    public String name()
-    {
-        return name;
-    }
-
-    public Annotation constraint()
-    {
-        return constraint;
-    }
-
-    public Object value()
-    {
-        return value;
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolationException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolationException.java
 
b/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolationException.java
index a007a11..c54d35d 100644
--- 
a/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolationException.java
+++ 
b/core/api/src/main/java/org/apache/polygene/api/constraint/ConstraintViolationException.java
@@ -20,23 +20,22 @@
 package org.apache.polygene.api.constraint;
 
 import java.lang.annotation.Annotation;
-import java.lang.reflect.Member;
 import java.lang.reflect.Type;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
-import java.util.MissingResourceException;
+import java.util.Objects;
 import java.util.ResourceBundle;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-import org.apache.polygene.api.composite.Composite;
+import org.apache.polygene.api.composite.CompositeDescriptor;
+import org.apache.polygene.api.entity.EntityDescriptor;
 import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.util.Classes;
 
-import static java.util.stream.Collectors.joining;
-
 /**
  * This Exception is thrown when there is one or more Constraint Violations in 
a method
  * call.
@@ -48,65 +47,49 @@ import static java.util.stream.Collectors.joining;
  */
 public class ConstraintViolationException extends IllegalArgumentException
 {
-    private final Collection<ConstraintViolation> constraintViolations;
-    private String methodName;
-    private String mixinTypeName;
-    private String instanceToString;
-    private List<? extends Type> instanceTypes;
+    private static final boolean longNames = Boolean.getBoolean( 
"polygene.constraints.longNames" );
+    private static final String DEFAULT_PATTERN = "\n\tConstraint Violation(s) 
in {0} of types [{3}].\n";
+    private static final String ENTITY_DEFAULT_PATTERN = "\n\tConstraint 
Violation(s) in entity {0} with id=[{2}].\n";
+    private static final String SERVICE_DEFAULT_PATTERN = "\n\tConstraint 
Violation(s) in service {0} with id=[{2}].\n";
+    private static final String MIXIN_DEFAULT_PATTERN = "\t\t@{2}({3}) on 
{0}.{1}(). Parameter [{4}] does not allow value [{5}].\n";
 
-    public ConstraintViolationException( Composite instance, Member method,
-                                         Collection<ConstraintViolation> 
constraintViolations
-    )
-    {
-        this( instance.toString(), Classes.interfacesOf( instance.getClass() 
), method, constraintViolations );
-    }
-
-    public ConstraintViolationException( String instanceToString,
-                                         Stream<? extends Type> instanceTypes,
-                                         Member method,
-                                         Collection<ConstraintViolation> 
violations
-    )
-    {
-        this.instanceToString = instanceToString;
-        this.instanceTypes = instanceTypes.collect( Collectors.toList() );
-        mixinTypeName = method.getDeclaringClass().getName();
-        methodName = method.getName();
-        this.constraintViolations = violations;
-    }
+    private String instanceToString;                              // arg {0}
+    private Class<?> primaryType;                                 // arg {1}
+    private List<? extends Type> instanceTypes;                   // arg {2}
+    private Collection<ValueConstraintViolation> constraintViolations; // arg 
{4} and {5}
+    private String identity;                                      // arg {6}
+    private boolean isService;
+    private boolean isEntity;
 
-    public ConstraintViolationException( Identity identity,
-                                         List<? extends Type> instanceTypes,
-                                         String mixinTypeName,
-                                         String methodName,
-                                         Collection<ConstraintViolation> 
violations
-    )
+    public ConstraintViolationException( Collection<ValueConstraintViolation> 
violations )
     {
-        this.instanceToString = identity.toString();
-        this.instanceTypes = instanceTypes;
-        this.mixinTypeName = mixinTypeName;
-        this.methodName = methodName;
-        this.constraintViolations = violations;
+        this.constraintViolations = new ArrayList<>();
+        this.constraintViolations.addAll( violations );
     }
 
-    public Collection<ConstraintViolation> constraintViolations()
+    public Collection<ValueConstraintViolation> constraintViolations()
     {
         return constraintViolations;
     }
 
     /**
-     * Creates localized messages of all the constraint violations that has 
occured.
+     * Creates localized message of all the constraint violations that has 
occured.
      * <p>
-     * The key 
"<code>polygene.constraint.<i><strong>CompositeType</strong></i>.<i><strong>methodName</strong></i></code>"
-     * will be used to lookup the text formatting
-     * pattern from the ResourceBundle, where 
<strong><code><i>CompositeType</i></code></strong> is the
-     * class name of the Composite where the constraint was violated. If such 
key does not exist, then the
-     * key &nbsp;"<code>polygene.constraint</code>" will be used, and if that 
one also doesn't exist, or
-     * the resourceBundle argument is null, then the default patterns will be 
used;
+     * Each ConstraintViolationException concerns one Composite instance, but 
may have many violations on that
+     * instance. For the composite instance related message following entries 
in the ResourceBundle will be searched
+     * for a pattern in the following order;
+     * <ol>
+     * 
<li><code>polygene.constraint.<i><strong>CompositeType</strong></i></code></li>
+     * <li><code>polygene.constraint.composite</code></li>
+     * </ol>
+     * where <strong><code><i>CompositeType</i></code></strong> is the
+     * class name of the Composite instance. If such key does not exist, or if 
the resourceBundle argument is null,
+     * then the default patterns will be used;
      * </p>
-     * <table summary="Localization of constraint vioations.">
+     * <table summary="Default localization of constraint violations for 
composite.">
      * <tr><th>Type of Composite</th><th>Pattern used</th></tr>
      * <tr><td>Composite</td>
-     * <td><code>Constraint Violation in {2}.{3} with constraint {4}, in 
composite \n{0} of type {1}</code></td>
+     * <td><code>\tConstraint Violation(s) in {0} with types {3}\n</code></td>
      * </tr>
      * <tr><td>EntityComposite</td>
      * <td><code>Constraint Violation in {2}.{3} with constraint {4}, in 
entity {1}[id={0}]</code></td>
@@ -115,144 +98,213 @@ public class ConstraintViolationException extends 
IllegalArgumentException
      * <td><code>Constraint Violation in {2}.{3} with constraint {4}, in 
service {0}</code></td>
      * </tr>
      * </table>
+     * The ResourceBundle arguments are defined as;
+     * <p>
+     * <p>
      * Then format each ConstraintViolation according to such pattern, where 
the following argument are passed;
      * <table summary="List of arguments 
available."><tr><th>Arg</th><th>Value</th></tr>
      * <tr>
      * <td>{0}</td>
+     * <td>Primary Type of Composite</td>
+     * </tr>
+     * <tr>
+     * <td>{1}</td>
      * <td>Composite instance toString()</td>
      * </tr>
      * <tr>
+     * <td>{2}</td>
+     * <td>Identity if composite implements HasIdentity</td>
+     * </tr>
+     * <tr>
+     * <td>{3}</td>
+     * <td>Comma-separeated list of types implemented by Composite</td>
+     * </tr>
+     * </table>
+     * <p>
+     * Once the message at the composite type level has been established, the 
message will contain each of the found
+     * violations. For each such violation, the resource bundle will be 
searched in the following order;
+     * <ol>
+     * 
<li><code>polygene.constraint.<i><strong>MixinType</strong></i>.<i><strong>member</strong></i></code></li>
+     * 
<li><code>polygene.constraint.<i><strong>MixinType</strong></i></code></li>
+     * <li><code>polygene.constraint.mixin</code></li>
+     * </ol>
+     * where <code><i><strong>MixinType</strong></i></code> refers to the 
mixin type of the member (method, field or
+     * constructor) and the <code><i><strong>member</strong></i></code> is the 
name of such Member.
+     * <table summary="Default localization of constraint violations for 
mixin.">
+     * <tr><th>Type of Composite</th><th>Pattern used</th></tr>
+     * <tr><td>Mixin</td>
+     * <td><code>\t\t@{2} {0}.{1} does not allow value [{4}]</code></td>
+     * </tr>
+     * </table>
+     * For these the ResourceBundle arguments are;
+     * <table summary="List of arguments 
available."><tr><th>Arg</th><th>Value</th></tr>
+     * <tr>
+     * <td>{0}</td>
+     * <td>Mixin Type Name</td>
+     * </tr>
+     * <tr>
      * <td>{1}</td>
-     * <td>CompositeType class name</td>
+     * <td>Mixin Member Name</td>
      * </tr>
      * <tr>
      * <td>{2}</td>
-     * <td>MixinType class name</td>
+     * <td>Annotation type</td>
      * </tr>
      * <tr>
      * <td>{3}</td>
-     * <td>MixinType method name</td>
+     * <td>Annotation toString</td>
      * </tr>
      * <tr>
      * <td>{4}</td>
-     * <td>Annotation toString()</td>
+     * <td>Name of the Member, see {@link Name}</td>
      * </tr>
      * <tr>
      * <td>{5}</td>
-     * <td>toString() of value passed as the argument, or "null" text if 
argument was null.</td>
+     * <td>Value attempted</td>
      * </tr>
      * </table>
-     * <p>
-     * <b>NOTE!!!</b> This class is still under construction and will be 
modified further.
-     * </p>
      *
      * @param bundle The ResourceBundle for Localization, or null if default 
formatting and locale to be used.
-     *
      * @return An array of localized messages of the violations incurred.
      */
-    public String[] localizedMessagesFrom( ResourceBundle bundle )
+    public String localizedMessageFrom( ResourceBundle bundle )
     {
-        String pattern = "Constraint violation in {0}.{1} for method ''{3}'' 
with constraint \"{4}({6})\", for value ''{5}''";
-
-        ArrayList<String> list = new ArrayList<>();
-        for( ConstraintViolation violation : constraintViolations )
+        Locale locale;
+        if( bundle != null )
         {
-            Locale locale;
-            if( bundle != null )
+            locale = bundle.getLocale();
+        }
+        else
+        {
+            locale = Locale.getDefault();
+        }
+        StringBuffer message = new StringBuffer();
+        {
+            String[] searchKeys = new String[]{ "polygene.constraint." + 
primaryType, "polygene.constraint.composite" };
+            String compositePattern = findPattern( bundle, searchKeys, 
defaultPattern() );
+            String types = instanceTypes == null
+                           ? null
+                           : instanceTypes.stream()
+                                          .map( this::nameOf )
+                                          .collect( Collectors.joining( "," ) 
);
+            String name;
+            if( longNames )
             {
-                try
-                {
-                    pattern = bundle.getString( "polygene.constraint." + 
mixinTypeName + "." + methodName );
-                }
-                catch( MissingResourceException e1 )
-                {
-                    try
-                    {
-                        pattern = bundle.getString( "polygene.constraint" );
-                    }
-                    catch( MissingResourceException e2 )
-                    {
-                        // ignore. The default pattern will be used.
-                    }
-                }
-                locale = bundle.getLocale();
+                name = primaryType.getName();
             }
             else
             {
-                locale = Locale.getDefault();
+                name = primaryType.getSimpleName();
             }
-            MessageFormat format = new MessageFormat( pattern, locale );
+            Object[] args = new Object[]{ name, instanceToString, identity, 
types };
+            MessageFormat formatter = new MessageFormat( compositePattern, 
locale );
+            formatter.format( args, message, null );
+        }
+        for( ValueConstraintViolation violation : constraintViolations )
+        {
+            String[] searchKeys = new String[]{ "polygene.constraint." + 
primaryType, "polygene.constraint.composite" };
+            String mixinPattern = findPattern( bundle, searchKeys, 
MIXIN_DEFAULT_PATTERN );
 
             Annotation annotation = violation.constraint();
-            String name = violation.name();
-            Object value = violation.value();
-            String classes;
-            if( instanceTypes.size() == 1 )
-            {
-                Type type = instanceTypes.stream().findFirst().get();
-                classes = Classes.RAW_CLASS.apply( type ).getSimpleName();
-            }
-            else
-            {
-                classes = "[" + instanceTypes.stream()
-                    .map( Classes.RAW_CLASS )
-                    .map( Class::getSimpleName ).collect( joining( "," ) ) + 
"]";
-            }
+            Class<? extends Annotation> annotatioType = 
annotation.annotationType();
+            Class<?> mixinType = violation.mixinType();
             Object[] args = new Object[]
                 {
-                    instanceToString,
-                    classes,
-                    mixinTypeName,
-                    methodName,
+                    longNames ? mixinType.getName() : 
mixinType.getSimpleName(),
+                    violation.methodName(),
+                    longNames ? annotatioType.getName() : 
annotatioType.getSimpleName(),
                     annotation.toString(),
-                    "" + value,
-                    name
+                    violation.name(),
+                    violation.value()
                 };
-            StringBuffer text = new StringBuffer();
-            format.format( args, text, null );
-            list.add( text.toString() );
+            MessageFormat formatter = new MessageFormat( mixinPattern, locale 
);
+            formatter.format( args, message, null );
         }
-        String[] result = new String[ list.size() ];
-        list.toArray( result );
+        String result = message.toString();
+        message.setLength( 0 ); // TODO: is this still needed to avoid JVM 
memory leak??
         return result;
     }
 
-    public String localizedMessage()
+    private String nameOf( Type type )
     {
-        String[] messages = localizedMessagesFrom( null );
-        StringBuilder result = new StringBuilder();
-        boolean first = true;
-        for( String message : messages )
+        Class<?> clazz = Classes.RAW_CLASS.apply( type );
+        if( longNames )
         {
-            if( !first )
-            {
-                result.append( ',' );
-            }
-            first = false;
-            result.append( message );
+            return clazz.getName();
+        }
+        else
+        {
+            return clazz.getSimpleName();
         }
-        return result.toString();
     }
 
     @Override
-    public String getLocalizedMessage()
+    public String getMessage()
     {
-        return localizedMessage();
+        return localizedMessageFrom( null );
     }
 
-    @Override
-    public String getMessage()
+    private String findPattern( ResourceBundle bundle, String[] searchKeys, 
String defaultPattern )
+    {
+        String compositePattern;
+        if( bundle != null )
+        {
+            compositePattern = Stream.of( searchKeys )
+                                     .map( name -> findPattern( bundle, name ) 
)
+                                     .filter( Objects::nonNull )
+                                     .findFirst().orElse( defaultPattern );
+        }
+        else
+        {
+            compositePattern = defaultPattern;
+        }
+        return compositePattern;
+    }
+
+    private String findPattern( ResourceBundle bundle, String name )
+    {
+        try
+        {
+            return bundle.getString( name );
+        }
+        catch( Exception e )
+        {
+            return null;
+        }
+    }
+
+    private String defaultPattern()
     {
-        return localizedMessage();
+        if( isEntity )
+        {
+            return ENTITY_DEFAULT_PATTERN;
+        }
+        if( isService )
+        {
+            return SERVICE_DEFAULT_PATTERN;
+        }
+        return DEFAULT_PATTERN;
     }
 
-    public String methodName()
+    public void setCompositeDescriptor( CompositeDescriptor descriptor )
     {
-        return methodName;
+        this.primaryType = descriptor.primaryType();
+        this.instanceTypes = descriptor.mixinTypes().collect( 
Collectors.toList() );
+        this.isEntity = descriptor instanceof EntityDescriptor;
+        this.isService = descriptor instanceof ServiceDescriptor;
+    }
+
+    public void setIdentity( Identity identity )
+    {
+        if( identity == null )
+        {
+            return;
+        }
+        this.identity = identity.toString();
     }
 
-    public String mixinTypeName()
+    public void setInstanceString( String instanceString )
     {
-        return mixinTypeName;
+        instanceToString = instanceString;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/constraint/ValueConstraintViolation.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/constraint/ValueConstraintViolation.java
 
b/core/api/src/main/java/org/apache/polygene/api/constraint/ValueConstraintViolation.java
new file mode 100644
index 0000000..1da5a4b
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/constraint/ValueConstraintViolation.java
@@ -0,0 +1,79 @@
+/*
+ *  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.polygene.api.constraint;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+/**
+ * When a constraint violation has occurred (ie Constraint.isValid has 
returned false) it
+ * is put in a collection of all violations that have occurred for this value 
check.
+ */
+public final class ValueConstraintViolation
+{
+    private final String name;
+    private final Annotation constraint;
+    private final Object value;
+    private Class<?> mixinType;
+    private String methodName;
+
+    public ValueConstraintViolation( String name, Annotation constraint, 
Object value )
+    {
+        this.name = name;
+        this.constraint = constraint;
+        this.value = value;
+    }
+
+    public String name()
+    {
+        return name;
+    }
+
+    public Annotation constraint()
+    {
+        return constraint;
+    }
+
+    public Object value()
+    {
+        return value;
+    }
+
+    public void setMixinType( Class<?> mixinType )
+    {
+        this.mixinType = mixinType;
+    }
+
+    public void setMethodName( String methodName )
+    {
+        this.methodName = methodName;
+    }
+
+    public Class<?> mixinType()
+    {
+        return mixinType;
+    }
+
+    public String methodName()
+    {
+        return methodName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectException.java
 
b/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectException.java
deleted file mode 100644
index 82b63bd..0000000
--- 
a/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectException.java
+++ /dev/null
@@ -1,57 +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.polygene.api.object;
-
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.polygene.api.common.InvalidApplicationException;
-
-/**
- * This exception is thrown if no visible Object of the requested type can be 
found.
- */
-public class NoSuchObjectException
-    extends InvalidApplicationException
-{
-    private static final long serialVersionUID = -1121690536365682511L;
-
-    private final String objectType;
-    private final String moduleName;
-
-    public NoSuchObjectException( String type, String moduleName, 
Stream<Class<?>> visible )
-    {
-        super( "Could not find any visible Object of type [" + type + "] in 
module ["
-               + moduleName
-               + "]. The visible types are: \n"
-               + visible.map( Class::getName ).collect( 
Collectors.joining("\n") )
-        );
-        this.objectType = type;
-        this.moduleName = moduleName;
-    }
-
-    public String objectType()
-    {
-        return objectType;
-    }
-
-    public String moduleName()
-    {
-        return moduleName;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectTypeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectTypeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectTypeException.java
new file mode 100644
index 0000000..af1801f
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/object/NoSuchObjectTypeException.java
@@ -0,0 +1,57 @@
+/*
+ *  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.polygene.api.object;
+
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.polygene.api.common.InvalidApplicationException;
+
+/**
+ * This exception is thrown if no visible Object of the requested type can be 
found.
+ */
+public class NoSuchObjectTypeException
+    extends InvalidApplicationException
+{
+    private static final long serialVersionUID = -1121690536365682511L;
+
+    private final String objectType;
+    private final String moduleName;
+
+    public NoSuchObjectTypeException( String type, String moduleName, 
Stream<Class<?>> visible )
+    {
+        super( "Could not find any visible Object of type [" + type + "] in 
module ["
+               + moduleName
+               + "]. The visible types are: \n"
+               + visible.map( Class::getName ).collect( 
Collectors.joining("\n") )
+        );
+        this.objectType = type;
+        this.moduleName = moduleName;
+    }
+
+    public String objectType()
+    {
+        return objectType;
+    }
+
+    public String moduleName()
+    {
+        return moduleName;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/object/ObjectFactory.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/object/ObjectFactory.java 
b/core/api/src/main/java/org/apache/polygene/api/object/ObjectFactory.java
index fddeeb1..a13a5bf 100644
--- a/core/api/src/main/java/org/apache/polygene/api/object/ObjectFactory.java
+++ b/core/api/src/main/java/org/apache/polygene/api/object/ObjectFactory.java
@@ -36,10 +36,10 @@ public interface ObjectFactory
      * @return new objects.
      *
      * @throws ConstructionException Thrown if instantiation fails.
-     * @throws NoSuchObjectException Thrown if {@code type} class is not an 
object.
+     * @throws NoSuchObjectTypeException Thrown if {@code type} class is not 
an object.
      */
     <T> T newObject( Class<T> type, Object... uses )
-        throws NoSuchObjectException, ConstructionException;
+        throws NoSuchObjectTypeException, ConstructionException;
 
     /**
      * Inject an existing instance. Only fields and methods will be called.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceException.java
 
b/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceException.java
deleted file mode 100644
index 3b98272..0000000
--- 
a/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceException.java
+++ /dev/null
@@ -1,58 +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.polygene.api.service;
-
-import java.util.stream.Collectors;
-import org.apache.polygene.api.composite.CompositeDescriptor;
-import org.apache.polygene.api.composite.ModelDescriptor;
-import org.apache.polygene.api.composite.NoSuchCompositeException;
-import org.apache.polygene.api.structure.TypeLookup;
-
-/**
- * Thrown when no visible service of the requested type is found.
- */
-public class NoSuchServiceException extends NoSuchCompositeException
-{
-    public NoSuchServiceException( String typeName, String moduleName, 
TypeLookup typeLookup )
-    {
-        super( "ServiceComposite", typeName, moduleName, formatVisibleTypes( 
typeLookup ) );
-    }
-
-    private static String formatVisibleTypes( TypeLookup typeLookup )
-    {
-        return typeLookup.allServices()
-            .map( NoSuchServiceException::typeOf )
-            .collect( Collectors.joining( "\n", "Visible service types 
are:\n", "" ) );
-    }
-
-    private static String typeOf( ModelDescriptor descriptor )
-    {
-        if( descriptor instanceof CompositeDescriptor )
-        {
-            return ( (CompositeDescriptor) descriptor 
).primaryType().getName();
-        }
-        return descriptor.types()
-                         .map( Class::getName )
-                         .sorted()
-                         .distinct()
-                         .collect( Collectors.joining( ",", "[", "]") );
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceTypeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceTypeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceTypeException.java
new file mode 100644
index 0000000..cc43627
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/service/NoSuchServiceTypeException.java
@@ -0,0 +1,47 @@
+/*
+ *  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.polygene.api.service;
+
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.polygene.api.composite.CompositeDescriptor;
+import org.apache.polygene.api.composite.ModelDescriptor;
+import org.apache.polygene.api.composite.NoSuchCompositeTypeException;
+import org.apache.polygene.api.structure.TypeLookup;
+
+/**
+ * Thrown when no visible service of the requested type is found.
+ */
+public class NoSuchServiceTypeException extends NoSuchCompositeTypeException
+{
+    public NoSuchServiceTypeException( String typeName, String moduleName, 
TypeLookup typeLookup )
+    {
+        super( "ServiceComposite", typeName, moduleName, typeLookup );
+    }
+
+    @Override
+    protected Stream<? extends CompositeDescriptor> descriptors( TypeLookup 
typeLookup )
+    {
+        return typeLookup.allServices()
+                         .filter( descriptor -> descriptor instanceof 
ServiceDescriptor )
+                         .map( descriptor -> (ServiceDescriptor) descriptor );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/service/ServiceFinder.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/service/ServiceFinder.java 
b/core/api/src/main/java/org/apache/polygene/api/service/ServiceFinder.java
index 8e7e9d5..28389ae 100644
--- a/core/api/src/main/java/org/apache/polygene/api/service/ServiceFinder.java
+++ b/core/api/src/main/java/org/apache/polygene/api/service/ServiceFinder.java
@@ -50,10 +50,10 @@ public interface ServiceFinder
      *
      * @return a ServiceReference if one is found
      *
-     * @throws NoSuchServiceException if no service of serviceType is found
+     * @throws NoSuchServiceTypeException if no service of serviceType is found
      */
     <T> ServiceReference<T> findService( Class<T> serviceType )
-        throws NoSuchServiceException;
+        throws NoSuchServiceTypeException;
 
     /**
      * Find a ServiceReference that implements the given type.
@@ -63,10 +63,10 @@ public interface ServiceFinder
      *
      * @return a ServiceReference if one is found
      *
-     * @throws NoSuchServiceException if no service of serviceType is found
+     * @throws NoSuchServiceTypeException if no service of serviceType is found
      */
     <T> ServiceReference<T> findService( Type serviceType )
-        throws NoSuchServiceException;
+        throws NoSuchServiceTypeException;
 
     /**
      * Find ServiceReferences that implements the given type.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/unitofwork/NoSuchEntityTypeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/unitofwork/NoSuchEntityTypeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/unitofwork/NoSuchEntityTypeException.java
index d6dbe8d..a020c6e 100644
--- 
a/core/api/src/main/java/org/apache/polygene/api/unitofwork/NoSuchEntityTypeException.java
+++ 
b/core/api/src/main/java/org/apache/polygene/api/unitofwork/NoSuchEntityTypeException.java
@@ -19,7 +19,9 @@
  */
 package org.apache.polygene.api.unitofwork;
 
-import org.apache.polygene.api.composite.NoSuchCompositeException;
+import java.util.stream.Stream;
+import org.apache.polygene.api.composite.CompositeDescriptor;
+import org.apache.polygene.api.composite.NoSuchCompositeTypeException;
 import org.apache.polygene.api.structure.TypeLookup;
 
 import static java.util.stream.Collectors.joining;
@@ -29,23 +31,16 @@ import static java.util.stream.Collectors.joining;
  * was not found during a lookup call.
  */
 public class NoSuchEntityTypeException
-    extends NoSuchCompositeException
+    extends NoSuchCompositeTypeException
 {
     public NoSuchEntityTypeException( String typeName, String moduleName, 
TypeLookup typeLookup )
     {
-        super( "EntityComposite", typeName, moduleName, formatVisibleTypes( 
typeLookup ) );
+        super( "EntityComposite", typeName, moduleName, typeLookup  );
     }
 
-    private static String formatVisibleTypes( TypeLookup typeLookup )
+    @Override
+    protected Stream<? extends CompositeDescriptor> descriptors( TypeLookup 
typeLookup )
     {
-        return typeLookup.allEntities()
-                         .map( descriptor -> {
-                             String moduleName = descriptor.module().name();
-                             String entityClassName = 
descriptor.primaryType().getName();
-                             return entityClassName + " in " + moduleName;
-                         } )
-                         .sorted()
-                         .distinct()
-                         .collect( joining( "\n", "Visible entity types 
are:\n", "" ) );
+        return typeLookup.allEntities();
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/unitofwork/UnitOfWork.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/unitofwork/UnitOfWork.java 
b/core/api/src/main/java/org/apache/polygene/api/unitofwork/UnitOfWork.java
index badbe4c..168a55c 100644
--- a/core/api/src/main/java/org/apache/polygene/api/unitofwork/UnitOfWork.java
+++ b/core/api/src/main/java/org/apache/polygene/api/unitofwork/UnitOfWork.java
@@ -23,7 +23,6 @@ import java.time.Instant;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import org.apache.polygene.api.association.AssociationDescriptor;
@@ -42,7 +41,6 @@ import org.apache.polygene.api.query.QueryBuilder;
 import org.apache.polygene.api.structure.MetaInfoHolder;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.usecase.Usecase;
-import org.apache.polygene.api.value.ValueBuilder;
 
 /**
  * All operations on entities goes through an UnitOfWork.

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueException.java
 
b/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueException.java
deleted file mode 100644
index b62b8e1..0000000
--- 
a/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueException.java
+++ /dev/null
@@ -1,46 +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.polygene.api.value;
-
-import org.apache.polygene.api.composite.NoSuchCompositeException;
-import org.apache.polygene.api.structure.TypeLookup;
-
-import static java.util.stream.Collectors.joining;
-
-/**
- * Thrown when no visible value of the requested type is found.
- */
-public class NoSuchValueException
-    extends NoSuchCompositeException
-{
-    public NoSuchValueException( String valueType, String moduleName, 
TypeLookup typeLookup )
-    {
-        super( "ValueComposite", valueType, moduleName, formatVisibleTypes( 
typeLookup ) );
-    }
-
-    private static String formatVisibleTypes( TypeLookup typeLookup )
-    {
-        return typeLookup.allValues()
-                         .map( descriptor -> 
descriptor.primaryType().getName() )
-                         .sorted()
-                         .distinct()
-                         .collect( joining( "\n", "Visible value types 
are:\n", "" ) );
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueTypeException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueTypeException.java
 
b/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueTypeException.java
new file mode 100644
index 0000000..77d2dc5
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/value/NoSuchValueTypeException.java
@@ -0,0 +1,45 @@
+/*
+ *  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.polygene.api.value;
+
+import java.util.stream.Stream;
+import org.apache.polygene.api.composite.CompositeDescriptor;
+import org.apache.polygene.api.composite.NoSuchCompositeTypeException;
+import org.apache.polygene.api.structure.TypeLookup;
+
+import static java.util.stream.Collectors.joining;
+
+/**
+ * Thrown when no visible value of the requested type is found.
+ */
+public class NoSuchValueTypeException
+    extends NoSuchCompositeTypeException
+{
+    public NoSuchValueTypeException( String valueType, String moduleName, 
TypeLookup typeLookup )
+    {
+        super( "ValueComposite", valueType, moduleName, typeLookup );
+    }
+
+    @Override
+    protected Stream<? extends CompositeDescriptor> descriptors( TypeLookup 
typeLookup )
+    {
+        return typeLookup.allValues();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/api/src/main/java/org/apache/polygene/api/value/ValueBuilderFactory.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/value/ValueBuilderFactory.java 
b/core/api/src/main/java/org/apache/polygene/api/value/ValueBuilderFactory.java
index 510c373..65cce37 100644
--- 
a/core/api/src/main/java/org/apache/polygene/api/value/ValueBuilderFactory.java
+++ 
b/core/api/src/main/java/org/apache/polygene/api/value/ValueBuilderFactory.java
@@ -41,11 +41,11 @@ public interface ValueBuilderFactory
      *
      * @return a new Value instance
      *
-     * @throws NoSuchValueException if no value extending the mixinType has 
been registered
+     * @throws NoSuchValueTypeException if no value extending the mixinType 
has been registered
      * @throws ConstructionException if the value could not be instantiated
      */
     <T> T newValue( Class<T> valueType )
-        throws NoSuchValueException, ConstructionException;
+        throws NoSuchValueTypeException, ConstructionException;
 
     /**
      * Create a builder for creating new Values that implements the given 
Value type.
@@ -56,10 +56,10 @@ public interface ValueBuilderFactory
      *
      * @return a ValueBuilder for creation of ValueComposites implementing the 
interface
      *
-     * @throws NoSuchValueException if no value extending the mixinType has 
been registered
+     * @throws NoSuchValueTypeException if no value extending the mixinType 
has been registered
      */
     <T> ValueBuilder<T> newValueBuilder( Class<T> valueType )
-        throws NoSuchValueException;
+        throws NoSuchValueTypeException;
 
     /**
      * Create a builder for creating a new Value starting with the given 
prototype.
@@ -70,7 +70,7 @@ public interface ValueBuilderFactory
      *
      * @return a ValueBuilder for creation of ValueComposites implementing the 
interface of the prototype
      *
-     * @throws NoSuchValueException if no value extending the mixinType has 
been registered
+     * @throws NoSuchValueTypeException if no value extending the mixinType 
has been registered
      */
     <T> ValueBuilder<T> newValueBuilderWithPrototype( T prototype );
 
@@ -87,7 +87,7 @@ public interface ValueBuilderFactory
      *
      * @return a ValueBuilder for creation of ValueComposites implementing the 
interface
      *
-     * @throws NoSuchValueException if no value extending the mixinType has 
been registered
+     * @throws NoSuchValueTypeException if no value extending the mixinType 
has been registered
      */
     <T> ValueBuilder<T> newValueBuilderWithState( Class<T> mixinType,
                                                   Function<PropertyDescriptor, 
Object> propertyFunction,
@@ -104,7 +104,7 @@ public interface ValueBuilderFactory
      *
      * @return a new Value instance
      *
-     * @throws NoSuchValueException if no value extending the mixinType has 
been registered
+     * @throws NoSuchValueTypeException if no value extending the mixinType 
has been registered
      * @throws ConstructionException if the value could not be instantiated
      */
     <T> T newValueFromSerializedState( Class<T> valueType, String 
serializedState );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/bootstrap/src/main/java/org/apache/polygene/bootstrap/AssemblyReportException.java
----------------------------------------------------------------------
diff --git 
a/core/bootstrap/src/main/java/org/apache/polygene/bootstrap/AssemblyReportException.java
 
b/core/bootstrap/src/main/java/org/apache/polygene/bootstrap/AssemblyReportException.java
index f3c933c..4a2211e 100644
--- 
a/core/bootstrap/src/main/java/org/apache/polygene/bootstrap/AssemblyReportException.java
+++ 
b/core/bootstrap/src/main/java/org/apache/polygene/bootstrap/AssemblyReportException.java
@@ -22,6 +22,7 @@ package org.apache.polygene.bootstrap;
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -29,10 +30,10 @@ import java.util.stream.Collectors;
  */
 public class AssemblyReportException extends AssemblyException
 {
-    private List<Throwable> problems;
+    private Set<Throwable> problems;
     private String modelReport;
 
-    public AssemblyReportException( List<Throwable> problems )
+    public AssemblyReportException( Set<Throwable> problems )
     {
         this.problems = problems;
     }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/runtime/src/main/java/org/apache/polygene/runtime/association/AbstractAssociationModel.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/polygene/runtime/association/AbstractAssociationModel.java
 
b/core/runtime/src/main/java/org/apache/polygene/runtime/association/AbstractAssociationModel.java
index 052ba02..166c601 100644
--- 
a/core/runtime/src/main/java/org/apache/polygene/runtime/association/AbstractAssociationModel.java
+++ 
b/core/runtime/src/main/java/org/apache/polygene/runtime/association/AbstractAssociationModel.java
@@ -123,19 +123,13 @@ public class AbstractAssociationModel<AT>
     public void checkConstraints( Object value )
         throws ConstraintViolationException
     {
-        if( constraints != null )
-        {
-            constraints.checkConstraints( value, accessor );
-        }
+        constraints.checkConstraints( value, accessor );
     }
 
     public void checkAssociationConstraints( AbstractAssociation association )
         throws ConstraintViolationException
     {
-        if( associationConstraints != null )
-        {
-            associationConstraints.checkConstraints( association, accessor );
-        }
+        associationConstraints.checkConstraints( association, accessor );
     }
 
     public AssociationInfo builderInfo()

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/CompositeAssemblyImpl.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/CompositeAssemblyImpl.java
 
b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/CompositeAssemblyImpl.java
index bc3993b..cb1c751 100644
--- 
a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/CompositeAssemblyImpl.java
+++ 
b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/CompositeAssemblyImpl.java
@@ -26,6 +26,7 @@ import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -210,7 +211,7 @@ public abstract class CompositeAssemblyImpl
                                      List<Class<?>> mixinClasses
                                    )
     {
-        List<Throwable> exceptions = new ArrayList<>();
+        Set<Throwable> exceptions = new HashSet<>();
         Set<Class<?>> thisDependencies = new HashSet<>();
         types.stream()
              .peek( mixinType -> mixinsModel.addMixinType( mixinType ) )
@@ -259,7 +260,7 @@ public abstract class CompositeAssemblyImpl
                                        List<Class<?>> constraintClasses,
                                        List<Class<?>> concernClasses,
                                        List<Class<?>> sideEffectClasses,
-                                       List<Throwable> exceptions,
+                                       Set<Throwable> exceptions,
                                        Set<Class<?>> thisDependencies )
     {
         try
@@ -476,11 +477,7 @@ public abstract class CompositeAssemblyImpl
             optional,
             constraintClasses,
             accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
+        ValueConstraintsInstance valueConstraintsInstance = 
valueConstraintsModel.newInstance();
         MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
         UseDefaults useDefaultsDeclaration = metaInfo.get( UseDefaults.class );
         Object initialValue = stateDeclarations.initialValueOf( accessor );
@@ -506,17 +503,19 @@ public abstract class CompositeAssemblyImpl
                                            )
     {
         List<ValueConstraintsModel> parameterConstraintModels = 
Collections.emptyList();
-        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+
+        Parameter[] parameters = method.getParameters();
         Type[] parameterTypes = method.getGenericParameterTypes();
         boolean constrained = false;
-        for( int i = 0; i < parameterAnnotations.length; i++ )
+        for( int i = 0; i < parameters.length; i++ )
         {
-            Annotation[] parameterAnnotation = parameterAnnotations[ i ];
+            Parameter param = parameters[i];
+
+            Annotation[] parameterAnnotation = param.getAnnotations();
 
             Name nameAnnotation = (Name) of( parameterAnnotation ).filter( 
isType( Name.class ) )
                                                                   
.findFirst().orElse( null );
-            String name = nameAnnotation == null ? "param" + ( i + 1 ) : 
nameAnnotation.value();
-
+            String name = nameAnnotation == null ? param.getName() : 
nameAnnotation.value();
             boolean optional = of( parameterAnnotation )
                 .anyMatch( isType( Optional.class ) );
             ValueConstraintsModel parameterConstraintsModel = constraintsFor(
@@ -865,29 +864,23 @@ public abstract class CompositeAssemblyImpl
         boolean optional = annotations.stream().anyMatch( isType( 
Optional.class ) );
 
         // Constraints for Association references
-        ValueConstraintsModel constraintsModel = constraintsFor( 
annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), 
optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance;
-        if( constraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = constraintsModel.newInstance();
-        }
-        else
-        {
-            valueConstraintsInstance = new ValueConstraintsInstance( 
Collections.emptyList(), ( (Member) accessor ).getName(), true );
-        }
+        ValueConstraintsModel constraintsModel =
+            constraintsFor( annotations.stream(),
+                            GenericAssociationInfo.associationTypeOf( accessor 
),
+                            ( (Member) accessor ).getName(),
+                            optional,
+                            constraintClasses,
+                            accessor );
+        ValueConstraintsInstance valueConstraintsInstance = 
constraintsModel.newInstance();
 
         // Constraints for the Association itself
-        constraintsModel = constraintsFor( annotations.stream(), 
Association.class, ( (Member) accessor ).getName(), optional, 
constraintClasses, accessor );
-        ValueConstraintsInstance associationValueConstraintsInstance;
-        if( constraintsModel.isConstrained() )
-        {
-            associationValueConstraintsInstance = 
constraintsModel.newInstance();
-        }
-        else
-        {
-            associationValueConstraintsInstance = new 
ValueConstraintsInstance( Collections.emptyList(), ( (Member) accessor 
).getName(), true );
-        }
+        constraintsModel = constraintsFor( annotations.stream(),
+                                           Association.class,
+                                           ( (Member) accessor ).getName(),
+                                           optional,
+                                           constraintClasses,
+                                           accessor );
+        ValueConstraintsInstance associationValueConstraintsInstance = 
constraintsModel.newInstance();
 
         MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
         return new AssociationModel( accessor, valueConstraintsInstance, 
associationValueConstraintsInstance, metaInfo );
@@ -901,21 +894,24 @@ public abstract class CompositeAssemblyImpl
         boolean optional = annotations.stream().anyMatch( isType( 
Optional.class ) );
 
         // Constraints for entities in ManyAssociation
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( 
annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), 
optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
+        ValueConstraintsModel valueConstraintsModel =
+            constraintsFor( annotations.stream(),
+                            GenericAssociationInfo.associationTypeOf( accessor 
),
+                            ( (Member) accessor ).getName(),
+                            optional,
+                            constraintClasses,
+                            accessor );
+        ValueConstraintsInstance valueConstraintsInstance = 
valueConstraintsModel.newInstance();
 
         // Constraints for the ManyAssociation itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), 
ManyAssociation.class, ( (Member) accessor ).getName(), optional, 
constraintClasses, accessor );
-        ValueConstraintsInstance manyValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            manyValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
+        valueConstraintsModel = constraintsFor( annotations.stream(),
+                                                ManyAssociation.class,
+                                                ( (Member) accessor 
).getName(),
+                                                optional,
+                                                constraintClasses,
+                                                accessor );
+        ValueConstraintsInstance manyValueConstraintsInstance = 
valueConstraintsModel.newInstance();
+
         MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
         return new ManyAssociationModel( accessor, valueConstraintsInstance, 
manyValueConstraintsInstance, metaInfo );
     }
@@ -928,21 +924,24 @@ public abstract class CompositeAssemblyImpl
         boolean optional = annotations.stream().anyMatch( isType( 
Optional.class ) );
 
         // Constraints for entities in NamedAssociation
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( 
annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), 
optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
+        ValueConstraintsModel valueConstraintsModel =
+            constraintsFor( annotations.stream(),
+                            GenericAssociationInfo.associationTypeOf( accessor 
),
+                            ( (Member) accessor ).getName(),
+                            optional,
+                            constraintClasses,
+                            accessor );
+        ValueConstraintsInstance valueConstraintsInstance = 
valueConstraintsModel.newInstance();
 
         // Constraints for the NamedAssociation itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), 
NamedAssociation.class, ( (Member) accessor ).getName(), optional, 
constraintClasses, accessor );
-        ValueConstraintsInstance namedValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            namedValueConstraintsInstance = 
valueConstraintsModel.newInstance();
-        }
+        valueConstraintsModel = constraintsFor( annotations.stream(),
+                                                NamedAssociation.class,
+                                                ( (Member) accessor 
).getName(),
+                                                optional,
+                                                constraintClasses,
+                                                accessor );
+        ValueConstraintsInstance namedValueConstraintsInstance = 
valueConstraintsModel.newInstance();
+
         MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
         return new NamedAssociationModel( accessor, valueConstraintsInstance, 
namedValueConstraintsInstance, metaInfo );
     }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java
 
b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java
index 5c30117..d4cfa29 100644
--- 
a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java
+++ 
b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java
@@ -525,7 +525,7 @@ final class ModuleAssemblyImpl
             throws AssemblyException
     {
         addRequiredAssemblers();
-        List<Throwable> exceptions = new ArrayList<>();
+        Set<Throwable> exceptions = new HashSet<>();
         List<TransientModel> transientModels = new ArrayList<>();
         List<ObjectModel> objectModels = new ArrayList<>();
         List<ValueModel> valueModels = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/runtime/src/main/java/org/apache/polygene/runtime/composite/CompositeModel.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/CompositeModel.java
 
b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/CompositeModel.java
index 59ad428..72ab757 100644
--- 
a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/CompositeModel.java
+++ 
b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/CompositeModel.java
@@ -32,6 +32,7 @@ import org.apache.polygene.api.common.MetaInfo;
 import org.apache.polygene.api.common.Visibility;
 import org.apache.polygene.api.composite.Composite;
 import org.apache.polygene.api.composite.CompositeDescriptor;
+import org.apache.polygene.api.constraint.ConstraintViolationException;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.util.AccessibleObjects;
 import org.apache.polygene.api.util.HierarchicalVisitor;
@@ -228,7 +229,15 @@ public abstract class CompositeModel
     {
         try
         {
-            return compositeMethodsModel.invoke( mixins, proxy, method, args, 
module );
+            try
+            {
+                return compositeMethodsModel.invoke( mixins, proxy, method, 
args, module );
+            }
+            catch( ConstraintViolationException e )
+            {
+                e.setCompositeDescriptor(this);
+                throw e;
+            }
         }
         catch( Throwable throwable )
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/runtime/src/main/java/org/apache/polygene/runtime/composite/ConstraintsInstance.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/ConstraintsInstance.java
 
b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/ConstraintsInstance.java
index 23e8f98..efa9521 100644
--- 
a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/ConstraintsInstance.java
+++ 
b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/ConstraintsInstance.java
@@ -23,11 +23,11 @@ package org.apache.polygene.runtime.composite;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.stream.Stream;
-import org.apache.polygene.api.composite.Composite;
 import org.apache.polygene.api.composite.CompositeInstance;
-import org.apache.polygene.api.constraint.ConstraintViolation;
+import org.apache.polygene.api.constraint.ValueConstraintViolation;
 import org.apache.polygene.api.constraint.ConstraintViolationException;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.Identity;
 
 /**
  * JAVADOC
@@ -51,11 +51,11 @@ public final class ConstraintsInstance
         }
 
         // Check constraints
-        List<ConstraintViolation> violations = null;
+        List<ValueConstraintViolation> violations = null;
         for( int i = 0; i < params.length; i++ )
         {
             Object param = params[ i ];
-            List<ConstraintViolation> paramViolations = 
valueConstraintsInstances.get( i ).checkConstraints( param );
+            List<ValueConstraintViolation> paramViolations = 
valueConstraintsInstances.get( i ).checkConstraints( param );
             if( !paramViolations.isEmpty() )
             {
                 if( violations == null )
@@ -69,16 +69,20 @@ public final class ConstraintsInstance
         // Check if any constraint failed
         if( violations != null )
         {
-            if( instance instanceof Composite )
+            for( ValueConstraintViolation violation : violations )
             {
-                throw new ConstraintViolationException( (Composite) instance, 
method, violations );
+                violation.setMixinType( method.getDeclaringClass() );
+                violation.setMethodName( method.getName() );
             }
+            ConstraintViolationException exception = new 
ConstraintViolationException( violations );
+            Identity identity = instance instanceof HasIdentity ? ( 
(HasIdentity) instance ).identity().get() : null;
+            exception.setIdentity( identity );
             if( instance instanceof CompositeInstance )
             {
-                throw new ConstraintViolationException( ( (CompositeInstance) 
instance ).proxy(), method, violations );
+                instance = ( (CompositeInstance) instance ).proxy();
             }
-            Stream<Class<?>> types = Stream.of( instance.getClass() );
-            throw new ConstraintViolationException( instance.toString(), 
types, method, violations );
+            exception.setInstanceString( instance.toString() );
+            throw exception;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/559b38a5/core/runtime/src/main/java/org/apache/polygene/runtime/composite/FragmentInvocationHandler.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/FragmentInvocationHandler.java
 
b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/FragmentInvocationHandler.java
index f0dfca6..936db3c 100644
--- 
a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/FragmentInvocationHandler.java
+++ 
b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/FragmentInvocationHandler.java
@@ -84,7 +84,7 @@ abstract class FragmentInvocationHandler
                     // Stop removing if the originating method call has been 
located in the stack.
                     // For 'semi' and 'extensive' compaction, we don't and do 
the entire stack instead.
                     trace[ i ] = new StackTraceElement( proxy.getClass()
-                                                            .getInterfaces()[ 
0 ].getName(), method.getName(), null, -1 );
+                                                             .getInterfaces()[ 
0 ].getName(), method.getName(), null, -1 );
                     break; // Stop compacting this trace
                 }
             }
@@ -118,19 +118,22 @@ abstract class FragmentInvocationHandler
 
     private boolean isApplicationClass( String className )
     {
+        boolean jdkInternals = isJdkInternals( className );
         if( compactLevel == CompactLevel.semi )
         {
-            return !isJdkInternals( className );
+            return !jdkInternals;
         }
-        return !( className.endsWith( FragmentClassLoader.GENERATED_POSTFIX ) 
||
-                  className.startsWith( "org.apache.polygene.runtime" ) ||
-                  isJdkInternals( className ) );
+        boolean polygeneRuntime = className.startsWith( 
"org.apache.polygene.runtime" );
+        boolean stubClass = className.endsWith( 
FragmentClassLoader.GENERATED_POSTFIX );
+        return !( stubClass ||
+                  polygeneRuntime ||
+                  jdkInternals );
     }
 
     private boolean isJdkInternals( String className )
     {
         return className.startsWith( "java.lang.reflect" )
-               || className.startsWith( "jdk.internal.reflect" )
+               || className.startsWith( "reflect" )
                || className.startsWith( "com.sun.proxy" )
                || className.startsWith( "sun.reflect" );
     }

Reply via email to