You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2016/10/23 14:24:08 UTC

[27/28] zest-java git commit: ZEST-180, ZEST-186, ZEST-187, ZEST-188 Big Identity refactoring UnitOfWorkFactory is auto added to all modules that doesn't declare one IdentityGenerator is auto-added to all modules that deosn't declare one. Removed DCI/DDD

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java b/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
index 3d41a08..8f4c37f 100644
--- a/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
+++ b/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
@@ -20,6 +20,7 @@
 
 package org.apache.zest.api.service.importer;
 
+import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.injection.scope.Structure;
 import org.apache.zest.api.service.ImportedServiceDescriptor;
 import org.apache.zest.api.service.ServiceFinder;
@@ -44,13 +45,13 @@ public class ServiceInstanceImporter<T>
 
     ServiceImporter<T> service;
 
-    String serviceId;
+    Identity serviceId;
 
     @Override
     public T importService( ImportedServiceDescriptor importedServiceDescriptor )
         throws ServiceImporterException
     {
-        serviceId = importedServiceDescriptor.metaInfo( String.class );
+        serviceId = importedServiceDescriptor.metaInfo( Identity.class );
 
         return serviceImporter().importService( importedServiceDescriptor );
     }
@@ -66,7 +67,7 @@ public class ServiceInstanceImporter<T>
     {
         if( service == null )
         {
-            for( ServiceReference<ServiceImporter> reference : finder.<ServiceImporter>findServices( ServiceImporter.class ) )
+            for( ServiceReference<ServiceImporter> reference : finder.findServices( ServiceImporter.class ) )
             {
                 if( reference.identity().equals( serviceId ) )
                 {

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/service/qualifier/ServiceQualifier.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/qualifier/ServiceQualifier.java b/core/api/src/main/java/org/apache/zest/api/service/qualifier/ServiceQualifier.java
index 58204de..1423d66 100644
--- a/core/api/src/main/java/org/apache/zest/api/service/qualifier/ServiceQualifier.java
+++ b/core/api/src/main/java/org/apache/zest/api/service/qualifier/ServiceQualifier.java
@@ -29,7 +29,7 @@ import org.apache.zest.api.service.ServiceReference;
  * <p>
  * Provide a Selector which does the actual
  * selection from the list. A common case is to select
- * based on identity of the service, which you can do this way:
+ * based on reference of the service, which you can do this way:
  * </p>
  *
  * <pre><code>
@@ -69,7 +69,7 @@ public abstract class ServiceQualifier
             @Override
             public boolean test( ServiceReference<?> service )
             {
-                return service.identity().equals( anId );
+                return service.identity().toString().equals( anId );
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/type/ValueType.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/type/ValueType.java b/core/api/src/main/java/org/apache/zest/api/type/ValueType.java
index 5b01620..ed95068 100644
--- a/core/api/src/main/java/org/apache/zest/api/type/ValueType.java
+++ b/core/api/src/main/java/org/apache/zest/api/type/ValueType.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.function.Function;
 import java.util.stream.Stream;
+import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.util.NullArgumentException;
 import org.apache.zest.functional.Iterables;
 
@@ -76,6 +77,11 @@ public class ValueType
         return false;
     }
 
+    public static boolean isIdentity( Object object )
+    {
+        return object instanceof Identity;
+    }
+
     private static boolean isArrayOfPrimitiveValues( Object array )
     {
         if( array instanceof String[]

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/unitofwork/EntityCompositeAlreadyExistsException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/unitofwork/EntityCompositeAlreadyExistsException.java b/core/api/src/main/java/org/apache/zest/api/unitofwork/EntityCompositeAlreadyExistsException.java
index 6fa5af5..d0e754e 100644
--- a/core/api/src/main/java/org/apache/zest/api/unitofwork/EntityCompositeAlreadyExistsException.java
+++ b/core/api/src/main/java/org/apache/zest/api/unitofwork/EntityCompositeAlreadyExistsException.java
@@ -22,7 +22,7 @@ package org.apache.zest.api.unitofwork;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
- * If you try to create an EntityComposite whose identity already exists,
+ * If you try to create an EntityComposite whose reference already exists,
  * then this exception will be thrown.
  */
 public class EntityCompositeAlreadyExistsException
@@ -30,16 +30,16 @@ public class EntityCompositeAlreadyExistsException
 {
     private static final long serialVersionUID = -7297710939536508481L;
 
-    private final EntityReference identity;
+    private final EntityReference reference;
 
-    public EntityCompositeAlreadyExistsException( EntityReference identity )
+    public EntityCompositeAlreadyExistsException( EntityReference reference)
     {
-        super( "EntityComposite (" + identity + ") already exists." );
-        this.identity = identity;
+        super( "EntityComposite (" + reference + ") already exists." );
+        this.reference = reference;
     }
 
-    public EntityReference identity()
+    public EntityReference reference()
     {
-        return identity;
+        return reference;
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/unitofwork/NoSuchEntityException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/unitofwork/NoSuchEntityException.java b/core/api/src/main/java/org/apache/zest/api/unitofwork/NoSuchEntityException.java
index 1c7fd90..689b053 100644
--- a/core/api/src/main/java/org/apache/zest/api/unitofwork/NoSuchEntityException.java
+++ b/core/api/src/main/java/org/apache/zest/api/unitofwork/NoSuchEntityException.java
@@ -19,7 +19,6 @@
  */
 package org.apache.zest.api.unitofwork;
 
-import java.util.function.Function;
 import java.util.stream.Stream;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.usecase.Usecase;
@@ -29,39 +28,39 @@ import static java.util.Arrays.stream;
 
 /**
  * This exception indicates that the requested Entity with the given
- * identity does not exist.
+ * reference does not exist.
  */
 public class NoSuchEntityException
     extends UnitOfWorkException
 {
-    private final EntityReference identity;
+    private final EntityReference reference;
     private final Usecase usecase;
     private final Class<?>[] mixinTypes;
 
-    public NoSuchEntityException( EntityReference identity, Class<?> mixinType, Usecase usecase )
+    public NoSuchEntityException(EntityReference reference, Class<?> mixinType, Usecase usecase )
     {
-        super( "Could not find entity (" + identity + ") of type " + mixinType.getName() + " in usecase '" + usecase.name() + "'" );
-        this.identity = identity;
+        super( "Could not find entity (" + reference + ") of type " + mixinType.getName() + " in usecase '" + usecase.name() + "'" );
+        this.reference = reference;
         this.usecase = usecase;
         this.mixinTypes = new Class<?>[]{ mixinType };
     }
 
-    public NoSuchEntityException( EntityReference identity, Class<?>[] mixinTypes, Usecase usecase )
+    public NoSuchEntityException(EntityReference reference, Class<?>[] mixinTypes, Usecase usecase )
     {
-        super( "Could not find entity (" + identity + ") of type " + toString( mixinTypes ) + " in usecase '" + usecase.name() + "'" );
-        this.identity = identity;
+        super( "Could not find entity (" + reference + ") of type " + toString( mixinTypes ) + " in usecase '" + usecase.name() + "'" );
+        this.reference = reference;
         this.mixinTypes = mixinTypes;
         this.usecase = usecase;
     }
 
-    public NoSuchEntityException( EntityReference identity, Stream<Class<?>> types, Usecase usecase )
+    public NoSuchEntityException(EntityReference reference, Stream<Class<?>> types, Usecase usecase )
     {
-        this( identity, types.toArray( Class[]::new ), usecase );
+        this(reference, types.toArray( Class[]::new ), usecase );
     }
 
-    public EntityReference identity()
+    public EntityReference reference()
     {
-        return identity;
+        return reference;
     }
 
     public Class<?>[] mixinTypes()

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/unitofwork/UnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/unitofwork/UnitOfWork.java b/core/api/src/main/java/org/apache/zest/api/unitofwork/UnitOfWork.java
index e792b8b..b8c2338 100644
--- a/core/api/src/main/java/org/apache/zest/api/unitofwork/UnitOfWork.java
+++ b/core/api/src/main/java/org/apache/zest/api/unitofwork/UnitOfWork.java
@@ -31,8 +31,9 @@ import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.composite.AmbiguousTypeException;
 import org.apache.zest.api.entity.EntityBuilder;
 import org.apache.zest.api.entity.EntityReference;
-import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.identity.HasIdentity;
 import org.apache.zest.api.entity.LifecycleException;
+import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.property.PropertyDescriptor;
 import org.apache.zest.api.query.Query;
 import org.apache.zest.api.query.QueryBuilder;
@@ -129,7 +130,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * EntityComposites implement the type then an AmbiguousTypeException will be thrown.
      * </p>
      * <p>
-     * The identity of the Entity will be generated by the IdentityGenerator of the Module of the EntityComposite.
+     * The reference of the Entity will be generated by the IdentityGenerator of the Module of the EntityComposite.
      * </p>
      *
      * @param type the mixin type that the EntityComposite must implement
@@ -150,7 +151,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * EntityComposites implement the type then an AmbiguousTypeException will be thrown.
      *
      * @param type     the mixin type that the EntityComposite must implement
-     * @param identity the identity of the new Entity
+     * @param identity the reference of the new Entity
      *
      * @return a new Entity
      *
@@ -158,7 +159,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * @throws AmbiguousTypeException    If several mixins implement the given type
      * @throws LifecycleException        if the entity cannot be created
      */
-    <T> T newEntity( Class<T> type, @Optional String identity )
+    <T> T newEntity( Class<T> type, @Optional Identity identity )
         throws NoSuchEntityTypeException, AmbiguousTypeException, LifecycleException;
 
     /**
@@ -184,14 +185,14 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * mixins implement the type then an AmbiguousTypeException will be thrown.
      *
      * @param type     the mixin type that the EntityComposite must implement
-     * @param identity the identity of the new Entity
+     * @param identity the reference of the new Entity
      *
      * @return a new EntityBuilder
      *
      * @throws NoSuchEntityTypeException if no EntityComposite type of the given mixin type has been registered
      * @throws AmbiguousTypeException    If several mixins implement the given type
      */
-    <T> EntityBuilder<T> newEntityBuilder( Class<T> type, @Optional String identity )
+    <T> EntityBuilder<T> newEntityBuilder( Class<T> type, @Optional Identity identity )
         throws NoSuchEntityTypeException, AmbiguousTypeException;
 
     /**
@@ -230,7 +231,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      *
      * @param <T>                      Entity type
      * @param type                     Entity type
-     * @param identity                 the identity of the new Entity
+     * @param identity                 the reference of the new Entity
      * @param propertyFunction         a function providing the state of properties
      * @param associationFunction      a function providing the state of associations
      * @param manyAssociationFunction  a function providing the state of many associations
@@ -241,7 +242,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * @throws NoSuchEntityTypeException If no mixins implements the given type
      * @throws AmbiguousTypeException    If several mixins implement the given type
      */
-    <T> EntityBuilder<T> newEntityBuilderWithState( Class<T> type, @Optional String identity,
+    <T> EntityBuilder<T> newEntityBuilderWithState( Class<T> type, @Optional Identity identity,
                                                     Function<PropertyDescriptor, Object> propertyFunction,
                                                     Function<AssociationDescriptor, EntityReference> associationFunction,
                                                     Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
@@ -250,7 +251,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
         throws NoSuchEntityTypeException, AmbiguousTypeException;
 
     /**
-     * Find an Entity of the given mixin type with the give identity. This
+     * Find an Entity of the given mixin type with the give reference. This
      * method verifies that it exists by asking the underlying EntityStore.
      *
      * @param type     of the entity
@@ -261,7 +262,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * @throws NoSuchEntityTypeException if no entity type could be found
      * @throws NoSuchEntityException     if the entity could not be found
      */
-    <T> T get( Class<T> type, String identity )
+    <T> T get( Class<T> type, Identity identity )
         throws NoSuchEntityTypeException, NoSuchEntityException;
 
     /**
@@ -398,7 +399,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      *
      * @return The Value
      */
-    <T extends Identity> T toValue( Class<T> primaryType, T entityComposite );
+    <T extends HasIdentity> T toValue(Class<T> primaryType, T entityComposite );
 
     /**
      * Converts all the entities referenced in the ManyAssociation into a List of values of the same type.
@@ -406,13 +407,13 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * <p>
      * All the referenced entities inside the association will be fetched from the underlying entity store,
      * which is potentially very expensive operation. Each of the fetched entities will be passed to
-     * {@link #toValue(Class, Identity)}, and its associations will NOT be converted into values, but remain
+     * {@link #toValue(Class, HasIdentity)}, and its associations will NOT be converted into values, but remain
      * {@link EntityReference} values. Hence there is no problem with circular references.
      * </p>
      *
      * <p>
      * For this to work, the type &lt;T&gt; must be registered at bootstrap as both an Entity and a Value, and
-     * as seen in the method signature, also be sub-type of {@link Identity}.
+     * as seen in the method signature, also be sub-type of {@link HasIdentity}.
      * </p>
      *
      * @param association The association of entities to be converted into values.
@@ -420,9 +421,9 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      *
      * @return A List of ValueComposites that has been converted from EntityComposites referenced by the Associations.
      *
-     * @see #toValue(Class, Identity)
+     * @see #toValue(Class, HasIdentity)
      */
-    <T extends Identity> List<T> toValueList( ManyAssociation<T> association );
+    <T extends HasIdentity> List<T> toValueList(ManyAssociation<T> association );
 
     /**
      * Converts all the entities referenced in the ManyAssociation into a Set of values of the same type.
@@ -431,13 +432,13 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * All the referenced entities inside the association will be fetched from the underlying entity store,
      * which is potentially very expensive operation. However, any duplicate EntityReferences in the association
      * will be dropped before the fetch occurs. Each of the fetched entities will be passed to
-     * {@link #toValue(Class, Identity)}, and its associations will NOT be converted into values, but remain
+     * {@link #toValue(Class, HasIdentity)}, and its associations will NOT be converted into values, but remain
      * {@link EntityReference} values. Hence there is no problem with circular references.
      * </p>
      *
      * <p>
      * For this to work, the type &lt;T&gt; must be registered at bootstrap as both an Entity and a Value, and
-     * as seen in the method signature, also be sub-type of {@link Identity}.
+     * as seen in the method signature, also be sub-type of {@link HasIdentity}.
      * </p>
      *
      * @param association The association of entities to be converted into values.
@@ -445,9 +446,9 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      *
      * @return A List of ValueComposites that has been converted from EntityComposites referenced by the Associations.
      *
-     * @see #toValue(Class, Identity)
+     * @see #toValue(Class, HasIdentity)
      */
-    <T extends Identity> Set<T> toValueSet( ManyAssociation<T> association );
+    <T extends HasIdentity> Set<T> toValueSet(ManyAssociation<T> association );
 
     /**
      * Converts the {@link NamedAssociation} into a Map with a String key and a ValueComposite as the value.
@@ -455,12 +456,12 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * <p>
      * A {@link NamedAssociation} is effectively a Map with a String key and an EntityReference as the value. The
      * EntityReference is fetched from the entity store and converted into a value of the same type.Each of the fetched
-     * entities will be passed to {@link #toValue(Class, Identity)}, and its associations will NOT be converted into
+     * entities will be passed to {@link #toValue(Class, HasIdentity)}, and its associations will NOT be converted into
      * values, but remain {@link EntityReference} values. Hence there is no problem with circular references.
      * </p>
      * <p>
      * For this to work, the type &lt;T&gt; must be registered at bootstrap as both an Entity and a Value, and
-     * as seen in the method signature, also be sub-type of {@link Identity}.
+     * as seen in the method signature, also be sub-type of {@link HasIdentity}.
      * </p>
      *
      * @param association The association of entities to be converted into values.
@@ -468,9 +469,9 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      *
      * @return A List of ValueComposites that has been converted from EntityComposites referenced by the Associations.
      *
-     * @see #toValue(Class, Identity)
+     * @see #toValue(Class, HasIdentity)
      */
-    <T extends Identity> Map<String, T> toValueMap( NamedAssociation<T> association );
+    <T extends HasIdentity> Map<String, T> toValueMap(NamedAssociation<T> association );
 
     /**
      * Converts the provided Value to an Entity of the same type.
@@ -514,7 +515,7 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      *
      * @return The new or updated Entity
      */
-    <T extends Identity> T toEntity( Class<T> primaryType, T valueComposite );
+    <T extends HasIdentity> T toEntity(Class<T> primaryType, T valueComposite );
 
     /**
      * The Module of the UnitOfWork is defined as the Module the UnitOfWorkFactory belonged to from where the

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/value/ValueComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/value/ValueComposite.java b/core/api/src/main/java/org/apache/zest/api/value/ValueComposite.java
index f6d1443..4ea2ef3 100644
--- a/core/api/src/main/java/org/apache/zest/api/value/ValueComposite.java
+++ b/core/api/src/main/java/org/apache/zest/api/value/ValueComposite.java
@@ -28,7 +28,7 @@ import org.apache.zest.api.mixin.Mixins;
 import org.apache.zest.api.property.Immutable;
 
 /**
- * ValueComposites are Composites that has state, and equality is defined from its values and not any identity nor
+ * ValueComposites are Composites that has state, and equality is defined from its values and not any reference nor
  * instance references.
  *
  * <ul>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/value/ValueDeserializer.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/value/ValueDeserializer.java b/core/api/src/main/java/org/apache/zest/api/value/ValueDeserializer.java
index a0b548a..8eca001 100644
--- a/core/api/src/main/java/org/apache/zest/api/value/ValueDeserializer.java
+++ b/core/api/src/main/java/org/apache/zest/api/value/ValueDeserializer.java
@@ -39,7 +39,7 @@ import org.apache.zest.api.type.ValueType;
  * </ul>
  * <p>
  * Nested plain values, EntityReferences, Collections, Maps, ValueComposites are supported.
- * EntityReferences are deserialized as their identity string.
+ * EntityReferences are deserialized as their reference string.
  * </p>
  * <p>
  * Plain values can be one of:

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/main/java/org/apache/zest/api/value/ValueSerializer.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/value/ValueSerializer.java b/core/api/src/main/java/org/apache/zest/api/value/ValueSerializer.java
index 16886fd..d9a5180 100644
--- a/core/api/src/main/java/org/apache/zest/api/value/ValueSerializer.java
+++ b/core/api/src/main/java/org/apache/zest/api/value/ValueSerializer.java
@@ -40,7 +40,7 @@ import org.apache.zest.api.composite.AmbiguousTypeException;
  * </ul>
  * <p>
  *     Nested plain values, EntityReferences, Iterables, Maps, ValueComposites and EntityComposites are supported.
- *     EntityComposites and EntityReferences are serialized as their identity string.
+ *     EntityComposites and EntityReferences are serialized as their reference string.
  * </p>
  * <p>
  *     Plain values can be one of:

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/test/java/org/apache/zest/api/OperatorsTest.java
----------------------------------------------------------------------
diff --git a/core/api/src/test/java/org/apache/zest/api/OperatorsTest.java b/core/api/src/test/java/org/apache/zest/api/OperatorsTest.java
index 9c34c65..99ccd5a 100644
--- a/core/api/src/test/java/org/apache/zest/api/OperatorsTest.java
+++ b/core/api/src/test/java/org/apache/zest/api/OperatorsTest.java
@@ -20,25 +20,26 @@
 package org.apache.zest.api;
 
 import java.util.function.Predicate;
-import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
-import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
-import org.junit.Assert;
-import org.junit.Test;
 import org.apache.zest.api.activation.ActivationException;
 import org.apache.zest.api.composite.Composite;
 import org.apache.zest.api.entity.EntityBuilder;
 import org.apache.zest.api.entity.EntityComposite;
+import org.apache.zest.api.identity.StringIdentity;
 import org.apache.zest.api.property.Property;
 import org.apache.zest.api.query.QueryBuilder;
 import org.apache.zest.api.query.QueryExpressions;
 import org.apache.zest.api.unitofwork.UnitOfWork;
 import org.apache.zest.api.unitofwork.UnitOfWorkCompletionException;
+import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
 import org.apache.zest.api.value.ValueComposite;
 import org.apache.zest.bootstrap.AssemblyException;
 import org.apache.zest.bootstrap.ModuleAssembly;
 import org.apache.zest.bootstrap.SingletonAssembler;
+import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
 import org.apache.zest.functional.Iterables;
 import org.apache.zest.test.EntityTestAssembler;
+import org.junit.Assert;
+import org.junit.Test;
 
 /**
  * TODO
@@ -70,7 +71,7 @@ public class OperatorsTest
 
         try
         {
-            EntityBuilder<TestEntity> entityBuilder = uow.newEntityBuilder( TestEntity.class, "123" );
+            EntityBuilder<TestEntity> entityBuilder = uow.newEntityBuilder( TestEntity.class, new StringIdentity( "123" ) );
             entityBuilder.instance().value().set( assembler.module().newValue( TestValue.class ) );
             TestEntity testEntity = entityBuilder.newInstance();
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/test/java/org/apache/zest/api/activation/ActivationEventsTest.java
----------------------------------------------------------------------
diff --git a/core/api/src/test/java/org/apache/zest/api/activation/ActivationEventsTest.java b/core/api/src/test/java/org/apache/zest/api/activation/ActivationEventsTest.java
index e1aee37..a9ce44a 100644
--- a/core/api/src/test/java/org/apache/zest/api/activation/ActivationEventsTest.java
+++ b/core/api/src/test/java/org/apache/zest/api/activation/ActivationEventsTest.java
@@ -121,7 +121,6 @@ public class ActivationEventsTest
             public void assemble( ModuleAssembly module )
                 throws AssemblyException
             {
-                module.withDefaultUnitOfWorkFactory();
                 module.importedServices( TestService.class ).
                         setMetaInfo( new TestServiceInstance() ).
                         importOnStartup();

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/api/src/test/java/org/apache/zest/api/unitofwork/RemovalTest.java
----------------------------------------------------------------------
diff --git a/core/api/src/test/java/org/apache/zest/api/unitofwork/RemovalTest.java b/core/api/src/test/java/org/apache/zest/api/unitofwork/RemovalTest.java
index caa8245..0dfa3c2 100644
--- a/core/api/src/test/java/org/apache/zest/api/unitofwork/RemovalTest.java
+++ b/core/api/src/test/java/org/apache/zest/api/unitofwork/RemovalTest.java
@@ -20,6 +20,8 @@
 
 package org.apache.zest.api.unitofwork;
 
+import org.apache.zest.api.identity.HasIdentity;
+import org.apache.zest.api.identity.StringIdentity;
 import org.junit.Test;
 import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.entity.EntityBuilder;
@@ -48,7 +50,7 @@ public class RemovalTest
         UnitOfWork uow = unitOfWorkFactory.newUnitOfWork();
         try
         {
-            EntityBuilder<TestEntity> builder = uow.newEntityBuilder( TestEntity.class, "123" );
+            EntityBuilder<TestEntity> builder = uow.newEntityBuilder( TestEntity.class, new StringIdentity( "123" ) );
             builder.instance().test().set( "habba" );
             TestEntity test = builder.newInstance();
             uow.remove( test );

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Assemblers.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Assemblers.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Assemblers.java
index c56f144..69563a0 100644
--- a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Assemblers.java
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Assemblers.java
@@ -20,7 +20,7 @@
 package org.apache.zest.bootstrap;
 
 /**
- * Assembler adapters for common use cases (visibility, identity, configuration).
+ * Assembler adapters for common use cases (visibility, reference, configuration).
  */
 public class Assemblers
 {
@@ -233,9 +233,9 @@ public class Assemblers
 
         @Override
         @SuppressWarnings( "unchecked" )
-        public final AssemblerType identifiedBy( String identity )
+        public final AssemblerType identifiedBy( String identityString )
         {
-            this.identity = identity;
+            this.identity = identityString;
             return (AssemblerType) this;
         }
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
index 36149dc..9cfa8d4 100644
--- a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
@@ -83,38 +83,6 @@ public interface ModuleAssembly
     ModuleAssembly withActivators( Class<? extends Activator<Module>>... activators );
 
     /**
-     * Adds the default UnitOfWorkFactory to this Module.
-     * <p>
-     * In versions &lt;3.0, UnitOfWork was built into the Core Runtime, and couldn't be custom made. In 3.0, the
-     * UnitOfWorkFactory is a regular Service that the Module instance will look up on demand.
-     * </p>
-     * <p>
-     * Typically, this method should be called, and it should be called first in the Assembler, so that
-     * it is possible to add Concerns and SideEffects to the default implementation of either the
-     * {@link org.apache.zest.api.unitofwork.UnitOfWorkFactory} or the
-     * {@link org.apache.zest.api.unitofwork.UnitOfWork}.
-     * </p>
-     * <p>
-     * Internally, this method is the equivalent of;
-     * </p>
-     * <pre><code>
-     *     new DefaultUnitOfWorkAssembler().assemble( module );
-     * </code>
-     * </pre>
-     * <p>
-     * and the {@link DefaultUnitOfWorkAssembler} does the equivalent of
-     * </p>
-     * <pre><code>
-     *     module.services( UnitOfWorkFactory.class ).withMixins( UnitOfWorkFactoryMixin.class );
-     *     module.transients( UnitOfWork.class ).withMixins( ModuleUnitOfWork.class );
-     * </code></pre>
-     * albeit those Mixins are in the Core Runtime and since Core Runtime is not a direct dependency of any
-     * other module, the classes are loaded with reflection. This may change in the future.
-     */
-    ModuleAssembly withDefaultUnitOfWorkFactory()
-        throws AssemblyException;
-
-    /**
      * Declare a list of TransientComposites for this Module. Use the TransientDeclaration that is returned to
      * declare further settings. Note that the TransientDeclaration works on all of the types specified.
      *

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java
index f5ec44e..4d0c2a2 100644
--- a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java
@@ -19,12 +19,12 @@
  */
 package org.apache.zest.bootstrap;
 
+import org.apache.zest.api.identity.Identifiable;
 import org.apache.zest.api.type.HasTypes;
 
 /**
  * This represents the assembly information of a single ServiceComposite in a Module.
  */
-public interface ServiceAssembly extends HasTypes
+public interface ServiceAssembly extends HasTypes, Identifiable
 {
-    String identity();
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/bootstrap/src/main/java/org/apache/zest/bootstrap/identity/DefaultIdentityGeneratorAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/identity/DefaultIdentityGeneratorAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/identity/DefaultIdentityGeneratorAssembler.java
new file mode 100644
index 0000000..dbcb34c
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/identity/DefaultIdentityGeneratorAssembler.java
@@ -0,0 +1,19 @@
+package org.apache.zest.bootstrap.identity;
+
+import org.apache.zest.api.identity.IdentityGenerator;
+import org.apache.zest.api.identity.UuidGeneratorMixin;
+import org.apache.zest.bootstrap.Assembler;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.ModuleAssembly;
+
+public class DefaultIdentityGeneratorAssembler
+    implements Assembler
+{
+
+    @Override
+    public void assemble(ModuleAssembly module)
+            throws AssemblyException
+    {
+        module.services(IdentityGenerator.class).withMixins(UuidGeneratorMixin.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/activation/ActivationDelegate.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/activation/ActivationDelegate.java b/core/runtime/src/main/java/org/apache/zest/runtime/activation/ActivationDelegate.java
index 37bbd37..0db2d57 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/activation/ActivationDelegate.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/activation/ActivationDelegate.java
@@ -30,6 +30,7 @@ import org.apache.zest.api.activation.ActivationEventListener;
 import org.apache.zest.api.activation.ActivationException;
 import org.apache.zest.api.activation.PassivationException;
 import org.apache.zest.api.composite.ModelDescriptor;
+import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.service.ServiceReference;
 
 import static org.apache.zest.api.activation.ActivationEvent.EventType.ACTIVATED;
@@ -315,7 +316,7 @@ public final class ActivationDelegate
         }
 
         @Override
-        public String identity()
+        public Identity identity()
         {
             return reference.identity();
         }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/association/AbstractAssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/association/AbstractAssociationInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/association/AbstractAssociationInstance.java
index f9c2c1c..6175cd4 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/association/AbstractAssociationInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/association/AbstractAssociationInstance.java
@@ -23,7 +23,7 @@ import java.lang.reflect.Type;
 import java.util.function.BiFunction;
 import org.apache.zest.api.association.AbstractAssociation;
 import org.apache.zest.api.entity.EntityReference;
-import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.identity.HasIdentity;
 
 /**
  * Implementation of AbstractAssociation. Includes helper methods for subclasses
@@ -70,17 +70,17 @@ public abstract class AbstractAssociationInstance<T>
             return null;
         }
 
-        return new EntityReference( ( (Identity) composite ).identity().get() );
+        return EntityReference.create(((HasIdentity) composite).identity().get());
     }
 
     protected void checkType( Object instance )
     {
 
-        if( instance instanceof Identity || instance == null )
+        if( instance instanceof HasIdentity || instance == null )
         {
             return;
         }
-        throw new IllegalArgumentException( "Object must be a subtype of org.apache.zest.api.identity.Identity: " + instance.getClass() );
+        throw new IllegalArgumentException( "Object must be a subtype of org.apache.zest.api.reference.Identity: " + instance.getClass() );
     }
 
     protected void checkImmutable()

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/association/AssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/association/AssociationInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/association/AssociationInstance.java
index bf0ce91..ae7729e 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/association/AssociationInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/association/AssociationInstance.java
@@ -26,7 +26,7 @@ import org.apache.zest.api.association.Association;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.AssociationWrapper;
 import org.apache.zest.api.entity.EntityReference;
-import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.identity.HasIdentity;
 import org.apache.zest.api.property.Property;
 
 /**
@@ -64,7 +64,7 @@ public final class AssociationInstance<T>
         associationInfo.checkConstraints( newValue );
 
         // Change association
-        associationState.set( EntityReference.create( (Identity) newValue ));
+        associationState.set( EntityReference.create( ((HasIdentity) newValue ).identity().get()));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/association/ManyAssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/association/ManyAssociationInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/association/ManyAssociationInstance.java
index 48ea507..848f7b8 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/association/ManyAssociationInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/association/ManyAssociationInstance.java
@@ -30,7 +30,7 @@ import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.ManyAssociation;
 import org.apache.zest.api.association.ManyAssociationWrapper;
 import org.apache.zest.api.entity.EntityReference;
-import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.identity.HasIdentity;
 import org.apache.zest.api.util.NullArgumentException;
 import org.apache.zest.functional.Iterables;
 import org.apache.zest.spi.entity.ManyAssociationState;
@@ -72,7 +72,7 @@ public class ManyAssociationInstance<T>
         checkImmutable();
         checkType( entity );
         associationInfo.checkConstraints( entity );
-        return manyAssociationState.add( i, new EntityReference( ( (Identity) entity ).identity().get() ) );
+        return manyAssociationState.add( i, EntityReference.create( ((HasIdentity) entity ).identity().get()) );
     }
 
     @Override
@@ -88,7 +88,7 @@ public class ManyAssociationInstance<T>
         checkImmutable();
         checkType( entity );
 
-        return manyAssociationState.remove( new EntityReference( ( (Identity) entity ).identity().get() ) );
+        return manyAssociationState.remove( EntityReference.create( ((HasIdentity) entity).identity().get() ) );
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/association/NamedAssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/association/NamedAssociationInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/association/NamedAssociationInstance.java
index 4e19fba..05c4539 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/association/NamedAssociationInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/association/NamedAssociationInstance.java
@@ -29,7 +29,7 @@ import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.NamedAssociation;
 import org.apache.zest.api.association.NamedAssociationWrapper;
 import org.apache.zest.api.entity.EntityReference;
-import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.identity.HasIdentity;
 import org.apache.zest.api.util.NullArgumentException;
 import org.apache.zest.spi.entity.NamedAssociationState;
 
@@ -76,7 +76,7 @@ public class NamedAssociationInstance<T>
         checkImmutable();
         checkType( entity );
         associationInfo.checkConstraints( entity );
-        return namedAssociationState.put( name, new EntityReference( ( (Identity) entity ).identity().get() ) );
+        return namedAssociationState.put( name, EntityReference.create( ((HasIdentity) entity).identity().get() ) );
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ImportedServiceAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ImportedServiceAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ImportedServiceAssemblyImpl.java
index 8123ce1..4890a53 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ImportedServiceAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ImportedServiceAssemblyImpl.java
@@ -27,6 +27,8 @@ import org.apache.zest.api.activation.Activator;
 import org.apache.zest.api.common.InvalidApplicationException;
 import org.apache.zest.api.common.MetaInfo;
 import org.apache.zest.api.common.Visibility;
+import org.apache.zest.api.identity.Identity;
+import org.apache.zest.api.identity.StringIdentity;
 import org.apache.zest.api.service.ServiceImporter;
 import org.apache.zest.api.service.importer.InstanceImporter;
 import org.apache.zest.api.structure.ModuleDescriptor;
@@ -69,11 +71,15 @@ public final class ImportedServiceAssemblyImpl
     {
         try
         {
-            String id = identity;
-            if( id == null )
+            Identity id;
+            if( identity == null )
             {
                 id = generateId( serviceModels, serviceType );
             }
+            else
+            {
+                id = new StringIdentity( identity );
+            }
 
             ImportedServiceModel serviceModel = new ImportedServiceModel( module,
                                                                           serviceType,
@@ -93,11 +99,11 @@ public final class ImportedServiceAssemblyImpl
     }
 
     @SuppressWarnings( "raw" )
-    private String generateId( List<ImportedServiceModel> serviceModels, Class serviceType )
+    private Identity generateId( List<ImportedServiceModel> serviceModels, Class serviceType )
     {
-        // Find identity that is not yet used
+        // Find reference that is not yet used
         int idx = 0;
-        String id = serviceType.getSimpleName();
+        Identity id = new StringIdentity( serviceType.getSimpleName() );
         boolean invalid;
         do
         {
@@ -107,7 +113,7 @@ public final class ImportedServiceAssemblyImpl
                 if( serviceModel.identity().equals( id ) )
                 {
                     idx++;
-                    id = serviceType.getSimpleName() + "_" + idx;
+                    id = new StringIdentity( serviceType.getSimpleName() + "_" + idx );
                     invalid = true;
                     break;
                 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ModuleAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ModuleAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ModuleAssemblyImpl.java
index 37fff7c..10e1b21 100755
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ModuleAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ModuleAssemblyImpl.java
@@ -20,14 +20,17 @@
 
 package org.apache.zest.runtime.bootstrap;
 
+import java.lang.reflect.UndeclaredThrowableException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import org.apache.zest.api.activation.Activator;
@@ -35,13 +38,18 @@ import org.apache.zest.api.common.MetaInfo;
 import org.apache.zest.api.common.Visibility;
 import org.apache.zest.api.composite.TransientComposite;
 import org.apache.zest.api.entity.EntityComposite;
-import org.apache.zest.api.entity.Identity;
+import org.apache.zest.api.identity.HasIdentity;
+import org.apache.zest.api.identity.Identity;
+import org.apache.zest.api.identity.IdentityGenerator;
+import org.apache.zest.api.identity.StringIdentity;
 import org.apache.zest.api.service.DuplicateServiceIdentityException;
 import org.apache.zest.api.service.ServiceImporter;
 import org.apache.zest.api.structure.Module;
 import org.apache.zest.api.type.HasTypes;
 import org.apache.zest.api.type.MatchTypeSpecification;
+import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
 import org.apache.zest.api.value.ValueComposite;
+import org.apache.zest.bootstrap.Assembler;
 import org.apache.zest.bootstrap.AssemblyException;
 import org.apache.zest.bootstrap.AssemblySpecifications;
 import org.apache.zest.bootstrap.AssemblyVisitor;
@@ -62,6 +70,7 @@ import org.apache.zest.bootstrap.TransientAssembly;
 import org.apache.zest.bootstrap.TransientDeclaration;
 import org.apache.zest.bootstrap.ValueAssembly;
 import org.apache.zest.bootstrap.ValueDeclaration;
+import org.apache.zest.bootstrap.identity.DefaultIdentityGeneratorAssembler;
 import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
 import org.apache.zest.functional.Iterables;
 import org.apache.zest.runtime.activation.ActivatorsModel;
@@ -80,6 +89,7 @@ import org.apache.zest.runtime.structure.ModuleModel;
 import org.apache.zest.runtime.value.ValueModel;
 import org.apache.zest.runtime.value.ValuesModel;
 
+import static java.util.stream.Collectors.toList;
 import static org.apache.zest.functional.Iterables.iterable;
 
 /**
@@ -89,24 +99,34 @@ import static org.apache.zest.functional.Iterables.iterable;
  * parameters then the declared metadata will apply to all types in the method
  * call.
  */
-public final class ModuleAssemblyImpl
-    implements ModuleAssembly
+final class ModuleAssemblyImpl
+        implements ModuleAssembly
 {
+    private static HashMap<Class, Assembler> defaultAssemblers;
+
     private final LayerAssembly layerAssembly;
     private String name;
     private final MetaInfo metaInfo = new MetaInfo();
-    private final List<Class<? extends Activator<Module>>> activators = new ArrayList<>();
 
+    private final List<Class<? extends Activator<Module>>> activators = new ArrayList<>();
     private final List<ServiceAssemblyImpl> serviceAssemblies = new ArrayList<>();
     private final Map<Class<?>, ImportedServiceAssemblyImpl> importedServiceAssemblies = new LinkedHashMap<>();
     private final Map<Class<? extends EntityComposite>, EntityAssemblyImpl> entityAssemblies = new LinkedHashMap<>();
     private final Map<Class<? extends ValueComposite>, ValueAssemblyImpl> valueAssemblies = new LinkedHashMap<>();
     private final Map<Class<? extends TransientComposite>, TransientAssemblyImpl> transientAssemblies = new LinkedHashMap<>();
+
     private final Map<Class<?>, ObjectAssemblyImpl> objectAssemblies = new LinkedHashMap<>();
 
     private final MetaInfoDeclaration metaInfoDeclaration = new MetaInfoDeclaration();
 
-    public ModuleAssemblyImpl( LayerAssembly layerAssembly, String name )
+    static
+    {
+        defaultAssemblers = new HashMap<>();
+        defaultAssemblers.put(UnitOfWorkFactory.class, new DefaultUnitOfWorkAssembler());
+        defaultAssemblers.put(IdentityGenerator.class, new DefaultIdentityGeneratorAssembler());
+    }
+
+    ModuleAssemblyImpl(LayerAssembly layerAssembly, String name)
     {
         this.layerAssembly = layerAssembly;
         this.name = name;
@@ -119,13 +139,13 @@ public final class ModuleAssemblyImpl
     }
 
     @Override
-    public ModuleAssembly module( String layerName, String moduleName )
+    public ModuleAssembly module(String layerName, String moduleName)
     {
-        return layerAssembly.application().module( layerName, moduleName );
+        return layerAssembly.application().module(layerName, moduleName);
     }
 
     @Override
-    public ModuleAssembly setName( String name )
+    public ModuleAssembly setName(String name)
     {
         this.name = name;
         return this;
@@ -137,509 +157,490 @@ public final class ModuleAssemblyImpl
         return name;
     }
 
-    public ModuleAssembly setMetaInfo( Object info )
+    public ModuleAssembly setMetaInfo(Object info)
     {
-        metaInfo.set( info );
+        metaInfo.set(info);
         return this;
     }
 
     @Override
     @SafeVarargs
-    public final ModuleAssembly withActivators( Class<? extends Activator<Module>>... activators )
+    public final ModuleAssembly withActivators(Class<? extends Activator<Module>>... activators)
     {
-        this.activators.addAll( Arrays.asList( activators ) );
+        this.activators.addAll(Arrays.asList(activators));
         return this;
     }
 
     @Override
-    public ModuleAssembly withDefaultUnitOfWorkFactory()
-        throws AssemblyException
-    {
-        new DefaultUnitOfWorkAssembler().assemble( this );
-        return this;
-    }
-
-    @Override
-    @SuppressWarnings( { "raw", "unchecked" } )
-    public ValueDeclaration values( Class<?>... valueTypes )
+    @SuppressWarnings("unchecked")
+    public ValueDeclaration values(Class<?>... valueTypes)
     {
         List<ValueAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class valueType : valueTypes )
+        for (Class valueType : valueTypes)
         {
-            if( valueAssemblies.containsKey( valueType ) )
+            if (valueAssemblies.containsKey(valueType))
             {
-                assemblies.add( valueAssemblies.get( valueType ) );
+                assemblies.add(valueAssemblies.get(valueType));
             }
             else
             {
-                ValueAssemblyImpl valueAssembly = new ValueAssemblyImpl( valueType );
-                valueAssemblies.put( valueType, valueAssembly );
-                assemblies.add( valueAssembly );
+                ValueAssemblyImpl valueAssembly = new ValueAssemblyImpl(valueType);
+                valueAssemblies.put(valueType, valueAssembly);
+                assemblies.add(valueAssembly);
             }
         }
 
-        return new ValueDeclarationImpl( assemblies );
+        return new ValueDeclarationImpl(assemblies);
     }
 
     @Override
-    public ValueDeclaration values( Predicate<? super ValueAssembly> specification )
+    public ValueDeclaration values(Predicate<? super ValueAssembly> specification)
     {
-        List<ValueAssemblyImpl> assemblies = new ArrayList<>();
-        for( ValueAssemblyImpl transientAssembly : valueAssemblies.values() )
-        {
-            if( specification.test( transientAssembly ) )
-            {
-                assemblies.add( transientAssembly );
-            }
-        }
-
-        return new ValueDeclarationImpl( assemblies );
+        List<ValueAssemblyImpl> assemblies = valueAssemblies.values().stream()
+                .filter(specification::test)
+                .collect(toList());
+        return new ValueDeclarationImpl(assemblies);
     }
 
     @Override
-    @SuppressWarnings( { "raw", "unchecked" } )
-    public TransientDeclaration transients( Class<?>... transientTypes )
+    @SuppressWarnings({"raw", "unchecked"})
+    public TransientDeclaration transients(Class<?>... transientTypes)
     {
         List<TransientAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class valueType : transientTypes )
+        for (Class valueType : transientTypes)
         {
-            if( transientAssemblies.containsKey( valueType ) )
+            if (transientAssemblies.containsKey(valueType))
             {
-                assemblies.add( transientAssemblies.get( valueType ) );
+                assemblies.add(transientAssemblies.get(valueType));
             }
             else
             {
-                TransientAssemblyImpl transientAssembly = new TransientAssemblyImpl( valueType );
-                transientAssemblies.put( valueType, transientAssembly );
-                assemblies.add( transientAssembly );
+                TransientAssemblyImpl transientAssembly = new TransientAssemblyImpl(valueType);
+                transientAssemblies.put(valueType, transientAssembly);
+                assemblies.add(transientAssembly);
             }
         }
 
-        return new TransientDeclarationImpl( assemblies );
+        return new TransientDeclarationImpl(assemblies);
     }
 
     @Override
-    public TransientDeclaration transients( Predicate<? super TransientAssembly> specification )
+    public TransientDeclaration transients(Predicate<? super TransientAssembly> specification)
     {
-        List<TransientAssemblyImpl> assemblies = new ArrayList<>();
-        for( TransientAssemblyImpl transientAssembly : transientAssemblies.values() )
-        {
-            if( specification.test( transientAssembly ) )
-            {
-                assemblies.add( transientAssembly );
-            }
-        }
+        List<TransientAssemblyImpl> assemblies = transientAssemblies.values().stream()
+                .filter(specification::test)
+                .collect(toList());
 
-        return new TransientDeclarationImpl( assemblies );
+        return new TransientDeclarationImpl(assemblies);
     }
 
     @Override
-    @SuppressWarnings( { "raw", "unchecked" } )
-    public EntityDeclaration entities( Class<?>... entityTypes )
+    @SuppressWarnings({"raw", "unchecked"})
+    public EntityDeclaration entities(Class<?>... entityTypes)
     {
         List<EntityAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class entityType : entityTypes )
+        for (Class entityType : entityTypes)
         {
-            if( entityAssemblies.containsKey( entityType ) )
+            if (entityAssemblies.containsKey(entityType))
             {
-                assemblies.add( entityAssemblies.get( entityType ) );
+                assemblies.add(entityAssemblies.get(entityType));
             }
             else
             {
-                EntityAssemblyImpl entityAssembly = new EntityAssemblyImpl( entityType );
-                entityAssemblies.put( entityType, entityAssembly );
-                assemblies.add( entityAssembly );
+                EntityAssemblyImpl entityAssembly = new EntityAssemblyImpl(entityType);
+                entityAssemblies.put(entityType, entityAssembly);
+                assemblies.add(entityAssembly);
             }
         }
 
-        return new EntityDeclarationImpl( assemblies );
+        return new EntityDeclarationImpl(assemblies);
     }
 
     @Override
-    public EntityDeclaration entities( Predicate<? super EntityAssembly> specification )
+    public EntityDeclaration entities(Predicate<? super EntityAssembly> specification)
     {
-        List<EntityAssemblyImpl> assemblies = new ArrayList<>();
-        for( EntityAssemblyImpl entityAssembly : entityAssemblies.values() )
-        {
-            if( specification.test( entityAssembly ) )
-            {
-                assemblies.add( entityAssembly );
-            }
-        }
+        List<EntityAssemblyImpl> assemblies = entityAssemblies.values().stream()
+                .filter(specification::test)
+                .collect(toList());
 
-        return new EntityDeclarationImpl( assemblies );
+        return new EntityDeclarationImpl(assemblies);
     }
 
     @Override
-    public ConfigurationDeclaration configurations( Class<?>... configurationTypes )
+    @SuppressWarnings("unchecked")
+    public ConfigurationDeclaration configurations(Class<?>... configurationTypes)
     {
         List<EntityAssemblyImpl> entityAssemblyList = new ArrayList<>();
 
-        for( Class entityType : configurationTypes )
+        for (Class entityType : configurationTypes)
         {
-            if( this.entityAssemblies.containsKey( entityType ) )
+            if (this.entityAssemblies.containsKey(entityType))
             {
-                entityAssemblyList.add( this.entityAssemblies.get( entityType ) );
+                entityAssemblyList.add(this.entityAssemblies.get(entityType));
             }
             else
             {
-                EntityAssemblyImpl entityAssembly = new EntityAssemblyImpl( entityType );
-                this.entityAssemblies.put( entityType, entityAssembly );
-                entityAssemblyList.add( entityAssembly );
+                EntityAssemblyImpl entityAssembly = new EntityAssemblyImpl(entityType);
+                this.entityAssemblies.put(entityType, entityAssembly);
+                entityAssemblyList.add(entityAssembly);
             }
         }
 
         List<ValueAssemblyImpl> valueAssemblyList = new ArrayList<>();
 
-        for( Class valueType : configurationTypes )
+        for (Class valueType : configurationTypes)
         {
-            if( valueAssemblies.containsKey( valueType ) )
+            if (valueAssemblies.containsKey(valueType))
             {
-                valueAssemblyList.add( valueAssemblies.get( valueType ) );
+                valueAssemblyList.add(valueAssemblies.get(valueType));
             }
             else
             {
-                ValueAssemblyImpl valueAssembly = new ValueAssemblyImpl( valueType );
-                valueAssemblies.put( valueType, valueAssembly );
-                valueAssemblyList.add( valueAssembly );
-                valueAssembly.types.add( Identity.class );
+                ValueAssemblyImpl valueAssembly = new ValueAssemblyImpl(valueType);
+                valueAssemblies.put(valueType, valueAssembly);
+                valueAssemblyList.add(valueAssembly);
+                valueAssembly.types.add(HasIdentity.class);
             }
         }
 
-        return new ConfigurationDeclarationImpl( entityAssemblyList, valueAssemblyList );
+        return new ConfigurationDeclarationImpl(entityAssemblyList, valueAssemblyList);
     }
 
     @Override
-    public ConfigurationDeclaration configurations( Predicate<HasTypes> specification )
+    public ConfigurationDeclaration configurations(Predicate<HasTypes> specification)
     {
-        Predicate<HasTypes> isConfigurationComposite = new MatchTypeSpecification( Identity.class );
-        specification = specification.and( isConfigurationComposite );
+        Predicate<HasTypes> isConfigurationComposite = new MatchTypeSpecification(HasIdentity.class);
+        specification = specification.and(isConfigurationComposite);
         List<EntityAssemblyImpl> entityAssmblyList = new ArrayList<>();
-        for( EntityAssemblyImpl entityAssembly : entityAssemblies.values() )
+        for (EntityAssemblyImpl entityAssembly : entityAssemblies.values())
         {
-            if( specification.test( entityAssembly ) )
+            if (specification.test(entityAssembly))
             {
-                entityAssmblyList.add( entityAssembly );
+                entityAssmblyList.add(entityAssembly);
             }
         }
         List<ValueAssemblyImpl> valueAssemblyList = new ArrayList<>();
-        for( ValueAssemblyImpl transientAssembly : valueAssemblies.values() )
+        for (ValueAssemblyImpl transientAssembly : valueAssemblies.values())
         {
-            if( specification.test( transientAssembly ) )
+            if (specification.test(transientAssembly))
             {
-                valueAssemblyList.add( transientAssembly );
+                valueAssemblyList.add(transientAssembly);
             }
         }
-        return new ConfigurationDeclarationImpl( entityAssmblyList, valueAssemblyList );
+        return new ConfigurationDeclarationImpl(entityAssmblyList, valueAssemblyList);
     }
 
     @Override
-    public ObjectDeclaration objects( Class<?>... objectTypes )
-        throws AssemblyException
+    public ObjectDeclaration objects(Class<?>... objectTypes)
+            throws AssemblyException
     {
         List<ObjectAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class<?> objectType : objectTypes )
+        for (Class<?> objectType : objectTypes)
         {
-            if( objectType.isInterface() )
+            if (objectType.isInterface())
             {
-                throw new AssemblyException( "Interfaces can not be Zest Objects." );
+                throw new AssemblyException("Interfaces can not be Zest Objects.");
             }
-            if( objectAssemblies.containsKey( objectType ) )
+            if (objectAssemblies.containsKey(objectType))
             {
-                assemblies.add( objectAssemblies.get( objectType ) );
+                assemblies.add(objectAssemblies.get(objectType));
             }
             else
             {
-                ObjectAssemblyImpl objectAssembly = new ObjectAssemblyImpl( objectType );
-                objectAssemblies.put( objectType, objectAssembly );
-                assemblies.add( objectAssembly );
+                ObjectAssemblyImpl objectAssembly = new ObjectAssemblyImpl(objectType);
+                objectAssemblies.put(objectType, objectAssembly);
+                assemblies.add(objectAssembly);
             }
         }
 
-        return new ObjectDeclarationImpl( assemblies );
+        return new ObjectDeclarationImpl(assemblies);
     }
 
     @Override
-    public ObjectDeclaration objects( Predicate<? super ObjectAssembly> specification )
+    public ObjectDeclaration objects(Predicate<? super ObjectAssembly> specification)
     {
-        List<ObjectAssemblyImpl> assemblies = new ArrayList<>();
-        for( ObjectAssemblyImpl objectAssembly : objectAssemblies.values() )
-        {
-            if( specification.test( objectAssembly ) )
-            {
-                assemblies.add( objectAssembly );
-            }
-        }
+        List<ObjectAssemblyImpl> assemblies = objectAssemblies.values().stream()
+                .filter(specification::test)
+                .collect(toList());
 
-        return new ObjectDeclarationImpl( assemblies );
+        return new ObjectDeclarationImpl(assemblies);
     }
 
     @Override
-    public ServiceDeclaration addServices( Class<?>... serviceTypes )
+    public ServiceDeclaration addServices(Class<?>... serviceTypes)
     {
         List<ServiceAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class<?> serviceType : serviceTypes )
+        for (Class<?> serviceType : serviceTypes)
         {
-            ServiceAssemblyImpl serviceAssembly = new ServiceAssemblyImpl( serviceType );
-            serviceAssemblies.add( serviceAssembly );
-            assemblies.add( serviceAssembly );
+            ServiceAssemblyImpl serviceAssembly = new ServiceAssemblyImpl(serviceType);
+            serviceAssemblies.add(serviceAssembly);
+            assemblies.add(serviceAssembly);
         }
 
-        return new ServiceDeclarationImpl( assemblies );
+        return new ServiceDeclarationImpl(assemblies);
     }
 
     @Override
-    public ServiceDeclaration services( Class<?>... serviceTypes )
+    public ServiceDeclaration services(Class<?>... serviceTypes)
     {
         List<ServiceAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class<?> serviceType : serviceTypes )
+        for (Class<?> serviceType : serviceTypes)
         {
-            if( Iterables.matchesAny( AssemblySpecifications.ofAnyType( serviceType ), serviceAssemblies ) )
+            if (Iterables.matchesAny(AssemblySpecifications.ofAnyType(serviceType), serviceAssemblies))
             {
-                Iterables.addAll( assemblies, Iterables.filter( AssemblySpecifications.ofAnyType( serviceType ), serviceAssemblies ) );
+                Iterables.addAll(assemblies, Iterables.filter(AssemblySpecifications.ofAnyType(serviceType), serviceAssemblies));
             }
             else
             {
-                ServiceAssemblyImpl serviceAssembly = new ServiceAssemblyImpl( serviceType );
-                serviceAssemblies.add( serviceAssembly );
-                assemblies.add( serviceAssembly );
+                ServiceAssemblyImpl serviceAssembly = new ServiceAssemblyImpl(serviceType);
+                serviceAssemblies.add(serviceAssembly);
+                assemblies.add(serviceAssembly);
             }
         }
 
-        return new ServiceDeclarationImpl( assemblies );
+        return new ServiceDeclarationImpl(assemblies);
     }
 
     @Override
-    public ServiceDeclaration services( Predicate<? super ServiceAssembly> specification )
+    public ServiceDeclaration services(Predicate<? super ServiceAssembly> specification)
     {
-        List<ServiceAssemblyImpl> assemblies = new ArrayList<>();
-        for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies )
-        {
-            if( specification.test( serviceAssembly ) )
-            {
-                assemblies.add( serviceAssembly );
-            }
-        }
-
-        return new ServiceDeclarationImpl( assemblies );
+        List<ServiceAssemblyImpl> assemblies = serviceAssemblies.stream()
+                .filter(specification::test)
+                .collect(toList());
+        return new ServiceDeclarationImpl(assemblies);
     }
 
     @Override
-    public ImportedServiceDeclaration importedServices( Class<?>... serviceTypes )
+    public ImportedServiceDeclaration importedServices(Class<?>... serviceTypes)
     {
         List<ImportedServiceAssemblyImpl> assemblies = new ArrayList<>();
 
-        for( Class<?> serviceType : serviceTypes )
+        for (Class<?> serviceType : serviceTypes)
         {
-            if( importedServiceAssemblies.containsKey( serviceType ) )
+            if (importedServiceAssemblies.containsKey(serviceType))
             {
-                assemblies.add( importedServiceAssemblies.get( serviceType ) );
+                assemblies.add(importedServiceAssemblies.get(serviceType));
             }
             else
             {
-                ImportedServiceAssemblyImpl serviceAssembly = new ImportedServiceAssemblyImpl( serviceType, this );
-                importedServiceAssemblies.put( serviceType, serviceAssembly );
-                assemblies.add( serviceAssembly );
+                ImportedServiceAssemblyImpl serviceAssembly = new ImportedServiceAssemblyImpl(serviceType, this);
+                importedServiceAssemblies.put(serviceType, serviceAssembly);
+                assemblies.add(serviceAssembly);
             }
         }
 
-        return new ImportedServiceDeclarationImpl( assemblies );
+        return new ImportedServiceDeclarationImpl(assemblies);
     }
 
     @Override
-    public ImportedServiceDeclaration importedServices( Predicate<? super ImportedServiceAssembly> specification )
+    public ImportedServiceDeclaration importedServices(Predicate<? super ImportedServiceAssembly> specification)
     {
-        List<ImportedServiceAssemblyImpl> assemblies = new ArrayList<>();
-        for( ImportedServiceAssemblyImpl objectAssembly : importedServiceAssemblies.values() )
-        {
-            if( specification.test( objectAssembly ) )
-            {
-                assemblies.add( objectAssembly );
-            }
-        }
+        List<ImportedServiceAssemblyImpl> assemblies = importedServiceAssemblies.values().stream()
+                .filter(specification::test)
+                .collect(toList());
 
-        return new ImportedServiceDeclarationImpl( assemblies );
+        return new ImportedServiceDeclarationImpl(assemblies);
     }
 
     @Override
-    public <T> MixinDeclaration<T> forMixin( Class<T> mixinType )
+    public <T> MixinDeclaration<T> forMixin(Class<T> mixinType)
     {
-        return metaInfoDeclaration.on( mixinType );
+        return metaInfoDeclaration.on(mixinType);
     }
 
     @Override
-    public <ThrowableType extends Throwable> void visit( AssemblyVisitor<ThrowableType> visitor )
-        throws ThrowableType
+    public <ThrowableType extends Throwable> void visit(AssemblyVisitor<ThrowableType> visitor)
+            throws ThrowableType
     {
-        visitor.visitModule( this );
+        visitor.visitModule(this);
 
-        for( TransientAssemblyImpl compositeDeclaration : transientAssemblies.values() )
+        for (TransientAssemblyImpl compositeDeclaration : transientAssemblies.values())
         {
-            visitor.visitComposite( new TransientDeclarationImpl( iterable( compositeDeclaration ) ) );
+            visitor.visitComposite(new TransientDeclarationImpl(iterable(compositeDeclaration)));
         }
 
-        for( EntityAssemblyImpl entityDeclaration : entityAssemblies.values() )
+        for (EntityAssemblyImpl entityDeclaration : entityAssemblies.values())
         {
-            visitor.visitEntity( new EntityDeclarationImpl( iterable( entityDeclaration ) ) );
+            visitor.visitEntity(new EntityDeclarationImpl(iterable(entityDeclaration)));
         }
 
-        for( ObjectAssemblyImpl objectDeclaration : objectAssemblies.values() )
+        for (ObjectAssemblyImpl objectDeclaration : objectAssemblies.values())
         {
-            visitor.visitObject( new ObjectDeclarationImpl( iterable( objectDeclaration ) ) );
+            visitor.visitObject(new ObjectDeclarationImpl(iterable(objectDeclaration)));
         }
 
-        for( ServiceAssemblyImpl serviceDeclaration : serviceAssemblies )
+        for (ServiceAssemblyImpl serviceDeclaration : serviceAssemblies)
         {
-            visitor.visitService( new ServiceDeclarationImpl( iterable( serviceDeclaration ) ) );
+            visitor.visitService(new ServiceDeclarationImpl(iterable(serviceDeclaration)));
         }
 
-        for( ImportedServiceAssemblyImpl importedServiceDeclaration : importedServiceAssemblies.values() )
+        for (ImportedServiceAssemblyImpl importedServiceDeclaration : importedServiceAssemblies.values())
         {
-            visitor.visitImportedService( new ImportedServiceDeclarationImpl( iterable( importedServiceDeclaration ) ) );
+            visitor.visitImportedService(new ImportedServiceDeclarationImpl(iterable(importedServiceDeclaration)));
         }
 
-        for( ValueAssemblyImpl valueDeclaration : valueAssemblies.values() )
+        for (ValueAssemblyImpl valueDeclaration : valueAssemblies.values())
         {
-            visitor.visitValue( new ValueDeclarationImpl( iterable( valueDeclaration ) ) );
+            visitor.visitValue(new ValueDeclarationImpl(iterable(valueDeclaration)));
         }
     }
 
-    ModuleModel assembleModule( LayerModel layerModel, AssemblyHelper helper )
-        throws AssemblyException
+    @SuppressWarnings("OptionalGetWithoutIsPresent")
+    ModuleModel assembleModule(LayerModel layerModel, AssemblyHelper helper)
+            throws AssemblyException
     {
+        addDefaultAssemblers();
         List<TransientModel> transientModels = new ArrayList<>();
         List<ObjectModel> objectModels = new ArrayList<>();
         List<ValueModel> valueModels = new ArrayList<>();
         List<ServiceModel> serviceModels = new ArrayList<>();
         List<ImportedServiceModel> importedServiceModels = new ArrayList<>();
         List<EntityModel> entityModels = new ArrayList<>();
+        ModuleModel moduleModel = new ModuleModel(name,
+                metaInfo,
+                layerModel,
+                new ActivatorsModel<>(activators),
+                new TransientsModel(transientModels),
+                new EntitiesModel(entityModels),
+                new ObjectsModel(objectModels),
+                new ValuesModel(valueModels),
+                new ServicesModel(serviceModels),
+                new ImportedServicesModel(importedServiceModels));
 
-        ModuleModel moduleModel = new ModuleModel( name,
-                                                   metaInfo,
-                                                   layerModel,
-                                                   new ActivatorsModel<>( activators ),
-                                                   new TransientsModel( transientModels ),
-                                                   new EntitiesModel( entityModels ),
-                                                   new ObjectsModel( objectModels ),
-                                                   new ValuesModel( valueModels ),
-                                                   new ServicesModel( serviceModels ),
-                                                   new ImportedServicesModel( importedServiceModels ) );
-
-        if( name == null )
+        if (name == null)
         {
-            throw new AssemblyException( "Module must have name set" );
+            throw new AssemblyException("Module must have name set");
         }
 
-        for( TransientAssemblyImpl compositeDeclaration : transientAssemblies.values() )
-        {
-            transientModels.add( compositeDeclaration.newTransientModel( moduleModel, metaInfoDeclaration, helper ) );
-        }
+        transientModels.addAll(transientAssemblies.values().stream()
+                .map(composite -> composite.newTransientModel(moduleModel, metaInfoDeclaration, helper))
+                .collect(toList()));
 
-        for( ValueAssemblyImpl valueDeclaration : valueAssemblies.values() )
-        {
-            valueModels.add( valueDeclaration.newValueModel( moduleModel, metaInfoDeclaration, helper ) );
-        }
+        valueModels.addAll(valueAssemblies.values().stream()
+                .map(value -> value.newValueModel(moduleModel, metaInfoDeclaration, helper))
+                .collect(toList()));
 
-        for( EntityAssemblyImpl entityDeclaration : entityAssemblies.values() )
-        {
-            entityModels.add( entityDeclaration.newEntityModel( moduleModel,
-                                                                metaInfoDeclaration,
-                                                                metaInfoDeclaration,
-                                                                metaInfoDeclaration,
-                                                                metaInfoDeclaration,
-                                                                helper ) );
-        }
+        entityModels.addAll(entityAssemblies.values().stream()
+                .map(entityDeclaration -> entityDeclaration.newEntityModel(moduleModel,
+                        metaInfoDeclaration,
+                        metaInfoDeclaration,
+                        metaInfoDeclaration,
+                        metaInfoDeclaration,
+                        helper))
+                .collect(Collectors.toList()));
 
-        for( ObjectAssemblyImpl objectDeclaration : objectAssemblies.values() )
+        for (ObjectAssemblyImpl objectDeclaration : objectAssemblies.values())
         {
-            objectDeclaration.addObjectModel( moduleModel, objectModels );
+            objectDeclaration.addObjectModel(moduleModel, objectModels);
         }
 
-        for( ServiceAssemblyImpl serviceDeclaration : serviceAssemblies )
+        for (ServiceAssemblyImpl serviceDeclaration : serviceAssemblies)
         {
-            if( serviceDeclaration.identity == null )
+            if (serviceDeclaration.identity == null)
             {
-                serviceDeclaration.identity = generateId( serviceDeclaration.types() );
+                serviceDeclaration.identity = generateId(serviceDeclaration.types());
             }
 
-            serviceModels.add( serviceDeclaration.newServiceModel( moduleModel, metaInfoDeclaration, helper ) );
+            serviceModels.add(serviceDeclaration.newServiceModel(moduleModel, metaInfoDeclaration, helper));
         }
 
-        for( ImportedServiceAssemblyImpl importedServiceDeclaration : importedServiceAssemblies.values() )
+        for (ImportedServiceAssemblyImpl importedServiceDeclaration : importedServiceAssemblies.values())
         {
-            importedServiceDeclaration.addImportedServiceModel( moduleModel, importedServiceModels );
+            importedServiceDeclaration.addImportedServiceModel(moduleModel, importedServiceModels);
         }
 
         // Check for duplicate service identities
         Set<String> identities = new HashSet<>();
-        for( ServiceModel serviceModel : serviceModels )
+        for (ServiceModel serviceModel : serviceModels)
         {
-            String identity = serviceModel.identity();
-            if( identities.contains( identity ) )
+            String identity = serviceModel.identity().toString();
+            if (identities.contains(identity))
             {
                 throw new DuplicateServiceIdentityException(
-                    "Duplicated service identity: " + identity + " in module " + moduleModel.name()
+                        "Duplicated service reference: " + identity + " in module " + moduleModel.name()
                 );
             }
-            identities.add( identity );
+            identities.add(identity);
         }
-        for( ImportedServiceModel serviceModel : importedServiceModels )
+        for (ImportedServiceModel serviceModel : importedServiceModels)
         {
-            String identity = serviceModel.identity();
-            if( identities.contains( identity ) )
+            String identity = serviceModel.identity().toString();
+            if (identities.contains(identity))
             {
                 throw new DuplicateServiceIdentityException(
-                    "Duplicated service identity: " + identity + " in module " + moduleModel.name()
+                        "Duplicated service reference: " + identity + " in module " + moduleModel.name()
                 );
             }
-            identities.add( identity );
+            identities.add(identity);
         }
 
-        for( ImportedServiceModel importedServiceModel : importedServiceModels )
+        importedServiceModels.stream().filter(importedServiceModel ->
+                !StreamSupport.stream(objectModels.spliterator(), false)
+                        .anyMatch(model -> model.types().findFirst().get().equals(importedServiceModel.serviceImporter())))
+                .forEach(importedServiceModel ->
         {
-            if( !StreamSupport.stream( objectModels.spliterator(), false )
-                .anyMatch( model ->
-                               model.types().findFirst().get().equals( importedServiceModel.serviceImporter() ) )
-                )
-            {
-                Class<? extends ServiceImporter> serviceFactoryType = importedServiceModel.serviceImporter();
-                ObjectModel objectModel = new ObjectModel( moduleModel, serviceFactoryType, Visibility.module, new MetaInfo() );
-                objectModels.add( objectModel );
-            }
-        }
+            Class<? extends ServiceImporter> serviceFactoryType = importedServiceModel.serviceImporter();
+            ObjectModel objectModel = new ObjectModel(moduleModel, serviceFactoryType, Visibility.module, new MetaInfo());
+            objectModels.add(objectModel);
+        });
 
         return moduleModel;
     }
 
-    private String generateId( Stream<Class<?>> serviceTypes )
+    private void addDefaultAssemblers()
+            throws AssemblyException
+    {
+        try
+        {
+            defaultAssemblers.entrySet().stream()
+                    .filter(entry -> serviceAssemblies.stream().noneMatch(serviceAssembly -> serviceAssembly.hasType(entry.getKey())))
+                    .forEach(entry ->
+                    {
+                        try
+                        {
+                            entry.getValue().assemble(this);
+                        }
+                        catch (AssemblyException e)
+                        {
+                            throw new UndeclaredThrowableException(e);
+                        }
+                    });
+        }
+        catch (UndeclaredThrowableException e)
+        {
+            throw (AssemblyException) e.getUndeclaredThrowable();
+        }
+    }
+
+    private Identity generateId(Stream<Class<?>> serviceTypes)
     {
-        // Find service identity that is not yet used
+        // Find service reference that is not yet used
         Class<?> serviceType = serviceTypes.findFirst()
-            .orElse( null ); // Use the first, which *SHOULD* be the main serviceType
+                .orElse(null); // Use the first, which *SHOULD* be the main serviceType
         int idx = 0;
-        String id = serviceType.getSimpleName();
+        Identity id = new StringIdentity(serviceType.getSimpleName());
         boolean invalid;
         do
         {
             invalid = false;
-            for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies )
+            for (ServiceAssemblyImpl serviceAssembly : serviceAssemblies)
             {
-                if( serviceAssembly.identity() != null && serviceAssembly.identity().equals( id ) )
+                if (serviceAssembly.identity() != null && serviceAssembly.identity().equals(id))
                 {
                     idx++;
-                    id = serviceType.getSimpleName() + "_" + idx;
+                    id = new StringIdentity(serviceType.getSimpleName() + "_" + idx);
                     invalid = true;
                     break;
                 }
             }
         }
-        while( invalid );
+        while (invalid);
         return id;
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
index 6cdcaf4..268a819 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
@@ -28,6 +28,7 @@ import java.util.stream.Stream;
 import org.apache.zest.api.activation.Activator;
 import org.apache.zest.api.activation.Activators;
 import org.apache.zest.api.common.InvalidApplicationException;
+import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.service.ServiceComposite;
 import org.apache.zest.api.util.Annotations;
 import org.apache.zest.api.util.Classes;
@@ -47,7 +48,7 @@ import org.apache.zest.runtime.structure.ModuleModel;
 public final class ServiceAssemblyImpl extends CompositeAssemblyImpl
     implements ServiceAssembly
 {
-    String identity;
+    Identity identity;
     boolean instantiateOnStartup = false;
     List<Class<? extends Activator<?>>> activators = new ArrayList<>();
 
@@ -62,7 +63,7 @@ public final class ServiceAssemblyImpl extends CompositeAssemblyImpl
     }
 
     @Override
-    public String identity()
+    public Identity identity()
     {
         return identity;
     }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/103c59cb/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceDeclarationImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceDeclarationImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceDeclarationImpl.java
index 24acd66..0b015ba 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceDeclarationImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceDeclarationImpl.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.zest.api.activation.Activator;
 import org.apache.zest.api.common.Visibility;
+import org.apache.zest.api.identity.StringIdentity;
 import org.apache.zest.api.service.qualifier.ServiceTags;
 import org.apache.zest.bootstrap.ServiceDeclaration;
 
@@ -57,7 +58,7 @@ public final class ServiceDeclarationImpl
     {
         for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies )
         {
-            serviceAssembly.identity = identity;
+            serviceAssembly.identity = new StringIdentity( identity );
         }
         return this;
     }