polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject zest-qi4j git commit: Fix for ZEST-23. + Putting the toValue() and toEntity() into the UnitOfWork instead f the SPI. + Adding access to the EntityReference in Associations.
Date Wed, 03 Jun 2015 04:22:55 GMT
Repository: zest-qi4j
Updated Branches:
  refs/heads/ZEST-22_toEntity-toValue e6d2d6b59 -> 568fa2ff3


Fix for ZEST-23.
    + Putting the toValue() and toEntity() into the UnitOfWork instead f the SPI.
    + Adding access to the EntityReference in Associations.


Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/568fa2ff
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/568fa2ff
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/568fa2ff

Branch: refs/heads/ZEST-22_toEntity-toValue
Commit: 568fa2ff3fe8abb4ff66c286e8675ed7ad285e64
Parents: e6d2d6b
Author: Niclas Hedhman <niclas@hedhman.org>
Authored: Wed Jun 3 12:22:31 2015 +0800
Committer: Niclas Hedhman <niclas@hedhman.org>
Committed: Wed Jun 3 12:22:31 2015 +0800

----------------------------------------------------------------------
 core/api/src/main/java/org/qi4j/api/Qi4j.java   |  71 ------
 .../org/qi4j/api/association/Association.java   |   7 +
 .../api/association/AssociationWrapper.java     |   8 +
 .../qi4j/api/association/ManyAssociation.java   |  11 +
 .../api/association/ManyAssociationWrapper.java |   7 +
 .../qi4j/api/association/NamedAssociation.java  |   6 +
 .../association/NamedAssociationWrapper.java    |   7 +
 .../org/qi4j/api/entity/EntityReference.java    |   7 +
 .../org/qi4j/api/unitofwork/UnitOfWork.java     |  74 ++++++
 .../java/org/qi4j/runtime/Qi4jRuntimeImpl.java  | 213 -----------------
 .../AbstractAssociationInstance.java            |  31 +--
 .../association/AssociationInstance.java        |  13 +-
 .../association/ManyAssociationInstance.java    |  33 ++-
 .../association/NamedAssociationInstance.java   |  35 ++-
 .../runtime/structure/ModuleUnitOfWork.java     | 235 ++++++++++++++++++-
 .../unitofwork/EntityBuilderInstance.java       |  11 +-
 .../runtime/value/ValueWithAssociationTest.java |  53 ++++-
 .../qi4j/spi/value/ValueSerializerAdapter.java  | 129 +++++-----
 .../binding/internal/BoundAssociation.java      |   7 +
 .../binding/internal/BoundManyAssociation.java  |   7 +
 .../binding/internal/BoundNamedAssociation.java |   7 +
 .../swing/binding/internal/BoundProperty.java   |  11 +-
 22 files changed, 557 insertions(+), 426 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/Qi4j.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/Qi4j.java b/core/api/src/main/java/org/qi4j/api/Qi4j.java
index d8f2d29..0b40c4a 100644
--- a/core/api/src/main/java/org/qi4j/api/Qi4j.java
+++ b/core/api/src/main/java/org/qi4j/api/Qi4j.java
@@ -135,77 +135,6 @@ public interface Qi4j
     AssociationDescriptor associationDescriptorFor( AbstractAssociation association );
 
     /**
-     * Converts the provided Entity to a Value of the same type.
-     * This is a convenience method to convert an EntityComposite to a ValueComposite.
-     * <p/>
-     * All Property values are transferred across as-is, and the Association, ManyAssociation
-     * and NamedAssociatino values are kept in the ValueComposite as EntityReferences
-     * until they are dereferenced (get() and other methods), and IF a UnitOfWork is
-     * present at dereferencing the corresponding EntityCompoiste is retrieved from the
-     * EntityStore. If there is not an UnitOfWork present, an exception is thrown.
-     * <p/>
-     * For this to work, the Composites (both Entity and Value) must not declare the
-     * EntityComposite and ValueComposite super types, but rely on the declaration in
-     * the assembly, and also extend the Identity supertype.
-     *
-     * Example;
-     * <pre><code>
-     *     public interface Person extends Identity { ... };
-     *     public class MyAssembler
-     *     {
-     *         public void assemble( ModuleAssembly module )
-     *         {
-     *             module.values( Person.class );
-     *             module.entities( Person.class );
-     *         }
-     *     }
-     * </code></pre>
-     *
-     * @param primaryType The shared type for which the properties and associations will
-     *                    be converted. Properties outside this type will be ignored.
-     * @param entityComposite The entity to be convered.
-     */
-    <T extends Identity> T toValue( Class<T> primaryType, T entityComposite );
-
-    /**
-     * Converts the provided Value to an Entity of the same type.
-     * This is a convenience method to convert a ValueComposite to an EntityComposite.
-     * <p/>
-     * All Property values are transferred across as-is (no deep copy in case mutable
-     * types (DISCOURAGED!) are used), and the Association, ManyAssociation
-     * and NamedAssociatino that were in the ValueComposite as EntityReferences are
-     * transferred into the EntityComposite correctly, and can be dereferenced.
-     * <p/>
-     * This method MUST be called within a UnitOfWork.
-     * <p/>
-     * If an Entity with the Identity in the ValueComposite already exists, then that
-     * Entity is updated with the values from the ValueComposite. If an Entity of
-     * that Identity doesn't exist and new one is created.
-     * <p/>
-     * For this to work, the Composites (both Entity and Value) must not declare the
-     * EntityComposite and ValueComposite super types, but rely on the declaration in
-     * the assembly, and also extend the Identity supertype.
-     *
-     * Example;
-     * <pre><code>
-     *     public interface Person extends Identity { ... };
-     *     public class MyAssembler
-     *     {
-     *         public void assemble( ModuleAssembly module )
-     *         {
-     *             module.values( Person.class );
-     *             module.entities( Person.class );
-     *         }
-     *     }
-     * </code></pre>
-     *
-     * @param primaryType The shared type for which the properties and associations will
-     *                    be converted. Properties outside this type will be ignored.
-     * @param valueComposite The Value to be convered into an Entity.
-     */
-    <T extends Identity> T toEntity( Class<T> primaryType, T valueComposite );
-
-    /**
      * Function that returns the CompositeDescriptor of a Composite.
      */
     Function<Composite, CompositeDescriptor> FUNCTION_DESCRIPTOR_FOR = new Function<Composite, CompositeDescriptor>()

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/association/Association.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/Association.java b/core/api/src/main/java/org/qi4j/api/association/Association.java
index f262a8c..acd406f 100644
--- a/core/api/src/main/java/org/qi4j/api/association/Association.java
+++ b/core/api/src/main/java/org/qi4j/api/association/Association.java
@@ -14,6 +14,8 @@
 
 package org.qi4j.api.association;
 
+import org.qi4j.api.entity.EntityReference;
+
 /**
  * Association to a single EntityComposite.
  */
@@ -36,4 +38,9 @@ public interface Association<T> extends AbstractAssociation
      */
     void set( T associated )
         throws IllegalArgumentException, IllegalStateException;
+
+    /**
+     * @return the the reference of the associated entity.
+     */
+    EntityReference reference();
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
index 4e907de..fd5af6f 100644
--- a/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
+++ b/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
@@ -1,5 +1,7 @@
 package org.qi4j.api.association;
 
+import org.qi4j.api.entity.EntityReference;
+
 /**
  * If you want to catch getting and setting association, then create a GenericConcern
  * that wraps the Qi4j-supplied Association instance with AssociationWrappers. Override
@@ -34,6 +36,12 @@ public class AssociationWrapper
     }
 
     @Override
+    public EntityReference reference()
+    {
+        return next.reference();
+    }
+
+    @Override
     public int hashCode()
     {
         return next.hashCode();

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
index 707d53a..37d7211 100644
--- a/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
+++ b/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
@@ -16,12 +16,17 @@ package org.qi4j.api.association;
 
 import java.util.List;
 import java.util.Set;
+import org.qi4j.api.entity.EntityReference;
 
 /**
  * Association to a collection of entities.
  */
 public interface ManyAssociation<T> extends Iterable<T>, AbstractAssociation
 {
+    /**
+     * Returns the number of references in this association.
+     * @return the number of references in this association.
+     */
     int count();
 
     boolean contains( T entity );
@@ -37,4 +42,10 @@ public interface ManyAssociation<T> extends Iterable<T>, AbstractAssociation
     List<T> toList();
 
     Set<T> toSet();
+
+    /**
+     * Returns an unmodifiable Iterable of the references to the associated entities.
+     * @return the references to the associated entities.
+     */
+    Iterable<EntityReference> references();
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
index 748af83..c844f0b 100644
--- a/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
+++ b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
@@ -3,6 +3,7 @@ package org.qi4j.api.association;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import org.qi4j.api.entity.EntityReference;
 
 /**
  * If you want to catch calls to ManyAssociations, then create a GenericConcern
@@ -73,6 +74,12 @@ public class ManyAssociationWrapper
     }
 
     @Override
+    public Iterable<EntityReference> references()
+    {
+        return next.references();
+    }
+
+    @Override
     public Iterator<Object> iterator()
     {
         return next.iterator();

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
index e8abe32..9464eed 100644
--- a/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
+++ b/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
@@ -19,6 +19,7 @@
 package org.qi4j.api.association;
 
 import java.util.Map;
+import org.qi4j.api.entity.EntityReference;
 
 /**
  * Association to named Entities.
@@ -75,4 +76,9 @@ public interface NamedAssociation<T>
      */
     Map<String, T> toMap();
 
+    /**
+     * Returns an unmodifiable Iterable of the references to the associated entities.
+     * @return the references to the associated entities.
+     */
+    Iterable<EntityReference> references();
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
index 581948e..7d0640e 100644
--- a/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
+++ b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
@@ -20,6 +20,7 @@ package org.qi4j.api.association;
 
 import java.util.Iterator;
 import java.util.Map;
+import org.qi4j.api.entity.EntityReference;
 
 /**
  * If you want to catch calls to NamedAssociations, then create a GenericConcern
@@ -90,6 +91,12 @@ public class NamedAssociationWrapper
     }
 
     @Override
+    public Iterable<EntityReference> references()
+    {
+        return next.references();
+    }
+
+    @Override
     public int hashCode()
     {
         return next.hashCode();

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java b/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
index 60c4d1b..967647c 100644
--- a/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
+++ b/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
@@ -55,6 +55,13 @@ public final class EntityReference
         return new EntityReference( (EntityComposite) object );
     }
 
+    public static EntityReference create( Identity identity )
+    {
+        if( identity == null )
+            return null;
+        return new EntityReference( identity.identity().get() );
+    }
+
     private static final long serialVersionUID = 1L;
 
     private String identity;

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java b/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
index e17bc07..7721265 100644
--- a/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
+++ b/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
@@ -20,6 +20,7 @@ import org.qi4j.api.association.AssociationDescriptor;
 import org.qi4j.api.composite.AmbiguousTypeException;
 import org.qi4j.api.entity.EntityBuilder;
 import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
 import org.qi4j.api.entity.LifecycleException;
 import org.qi4j.api.property.PropertyDescriptor;
 import org.qi4j.api.query.Query;
@@ -348,4 +349,77 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
      * @param callback a callback to be unregistered with this UnitOfWork
      */
     void removeUnitOfWorkCallback( UnitOfWorkCallback callback );
+
+    /**
+     * Converts the provided Entity to a Value of the same type.
+     * This is a convenience method to convert an EntityComposite to a ValueComposite.
+     * <p/>
+     * All Property values are transferred across as-is, and the Association, ManyAssociation
+     * and NamedAssociatino values are kept in the ValueComposite as EntityReferences
+     * until they are dereferenced (get() and other methods), and IF a UnitOfWork is
+     * present at dereferencing the corresponding EntityCompoiste is retrieved from the
+     * EntityStore. If there is not an UnitOfWork present, an exception is thrown.
+     * <p/>
+     * For this to work, the Composites (both Entity and Value) must not declare the
+     * EntityComposite and ValueComposite super types, but rely on the declaration in
+     * the assembly, and also extend the Identity supertype.
+     *
+     * Example;
+     * <pre><code>
+     *     public interface Person extends Identity { ... };
+     *     public class MyAssembler
+     *     {
+     *         public void assemble( ModuleAssembly module )
+     *         {
+     *             module.values( Person.class );
+     *             module.entities( Person.class );
+     *         }
+     *     }
+     * </code></pre>
+     *
+     * @param primaryType The shared type for which the properties and associations will
+     *                    be converted. Properties outside this type will be ignored.
+     * @param entityComposite The entity to be convered.
+     */
+    <T extends Identity> T toValue( Class<T> primaryType, T entityComposite );
+
+    /**
+     * Converts the provided Value to an Entity of the same type.
+     * This is a convenience method to convert a ValueComposite to an EntityComposite.
+     * <p/>
+     * All Property values are transferred across as-is (no deep copy in case mutable
+     * types (DISCOURAGED!) are used), and the Association, ManyAssociation
+     * and NamedAssociatino that were in the ValueComposite as EntityReferences are
+     * transferred into the EntityComposite correctly, and can be dereferenced.
+     * <p/>
+     * This method MUST be called within a UnitOfWork.
+     * <p/>
+     * If an Entity with the Identity in the ValueComposite already exists, then that
+     * Entity is updated with the values from the ValueComposite. If an Entity of
+     * that Identity doesn't exist and new one is created.
+     * <p/>
+     * For this to work, the Composites (both Entity and Value) must not declare the
+     * EntityComposite and ValueComposite super types, but rely on the declaration in
+     * the assembly, and also extend the Identity supertype.
+     *
+     * Example;
+     * <pre><code>
+     *     public interface Person extends Identity { ... };
+     *     public class MyAssembler
+     *     {
+     *         public void assemble( ModuleAssembly module )
+     *         {
+     *             module.values( Person.class );
+     *             module.entities( Person.class );
+     *         }
+     *     }
+     * </code></pre>
+     *
+     * @param primaryType The shared type for which the properties and associations will
+     *                    be converted. Properties outside this type will be ignored.
+     * @param valueComposite The Value to be convered into an Entity.
+     */
+    <T extends Identity> T toEntity( Class<T> primaryType, T valueComposite );
+
+
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java b/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java
index 9b5dce7..23ba27b 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java
@@ -338,57 +338,6 @@ public final class Qi4jRuntimeImpl
         return (AssociationDescriptor) ( (AbstractAssociationInstance) association ).associationInfo();
     }
 
-    @Override
-    public <T extends Identity> T toValue( Class<T> primaryType, T entityComposite )
-    {
-        EntityDescriptor entityDescriptor = entityDescriptorFor( entityComposite );
-        Function<PropertyDescriptor, Object> propertyFunction = new ToValuePropertyMappingFunction<T>( entityComposite );
-        Function<AssociationDescriptor, EntityReference> assocationFunction = new ToValueAssociationMappingFunction<T>( entityComposite );
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssocFunction = new ToValueManyAssociationMappingFunction<T>( entityComposite );
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssocFunction = new ToValueNameAssociationMappingFunction<T>( entityComposite );
-
-        @SuppressWarnings( "unchecked" )
-        ValueBuilder<T> builder = moduleOf( entityComposite ).newValueBuilderWithState(
-            (Class<T>) entityDescriptor.primaryType(), propertyFunction, assocationFunction, manyAssocFunction, namedAssocFunction );
-        return builder.newInstance();
-    }
-
-    @Override
-    public <T extends Identity> T toEntity( Class<T> primaryType, T valueComposite )
-    {
-        Function<PropertyDescriptor, Object> propertyFunction = new ToEntityPropertyMappingFunction<T>( valueComposite );
-        Function<AssociationDescriptor, EntityReference> assocationFunction = new ToEntityAssociationMappingFunction<T>( valueComposite );
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssocFunction = new ToEntityManyAssociationMappingFunction<T>( valueComposite );
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssocFunction = new ToEntityNameAssociationMappingFunction<T>( valueComposite );
-
-        UnitOfWork uow = moduleOf( valueComposite ).currentUnitOfWork();
-        String identity = valueComposite.identity().get();
-        try
-        {
-            T entity = uow.get( primaryType, identity );
-            // If successful, then this entity is to by modified.
-            EntityInstance instance = EntityInstance.entityInstanceOf( (EntityComposite) entity );
-            EntityState state = instance.entityState();
-            FunctionStateResolver stateResolver = new FunctionStateResolver( propertyFunction,
-                                                                             assocationFunction,
-                                                                             manyAssocFunction,
-                                                                             namedAssocFunction );
-            EntityModel model = (EntityModel) EntityInstance.entityInstanceOf( (EntityComposite) entity ).descriptor();
-            stateResolver.populateState( model, state );
-            return entity;
-        }
-        catch( NoSuchEntityException e )
-        {
-            EntityBuilder<T> entityBuilder = uow.newEntityBuilderWithState( primaryType,
-                                                                            identity,
-                                                                            propertyFunction,
-                                                                            assocationFunction,
-                                                                            manyAssocFunction,
-                                                                            namedAssocFunction );
-            return entityBuilder.newInstance();
-        }
-    }
-
     // SPI
     @Override
     public EntityState entityStateOf( EntityComposite composite )
@@ -416,166 +365,4 @@ public final class Qi4jRuntimeImpl
         return ( (NamedAssociationInstance) assoc ).getEntityReferences();
     }
 
-    private class ToValuePropertyMappingFunction<T>
-        implements Function<PropertyDescriptor, Object>
-    {
-        private Object entity;
-
-        public ToValuePropertyMappingFunction( Object entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public Object map( PropertyDescriptor propertyDescriptor )
-        {
-            EntityState entityState = entityStateOf( (EntityComposite) entity );
-            return entityState.propertyValueOf( propertyDescriptor.qualifiedName() );
-        }
-    }
-
-    private class ToValueAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, EntityReference>
-    {
-        private final T entity;
-
-        public ToValueAssociationMappingFunction( T entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public EntityReference map( AssociationDescriptor associationDescriptor )
-        {
-            EntityState entityState = entityStateOf( (EntityComposite) entity );
-            return entityState.associationValueOf( associationDescriptor.qualifiedName() );
-        }
-    }
-
-    private class ToValueManyAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
-    {
-        private final T entity;
-
-        public ToValueManyAssociationMappingFunction( T entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public Iterable<EntityReference> map( AssociationDescriptor associationDescriptor )
-        {
-            EntityState entityState = entityStateOf( (EntityComposite) entity );
-            return entityState.manyAssociationValueOf( associationDescriptor.qualifiedName() );
-        }
-    }
-
-    private class ToValueNameAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
-    {
-        private final T entity;
-
-        public ToValueNameAssociationMappingFunction( T entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public Map<String, EntityReference> map( AssociationDescriptor associationDescriptor )
-        {
-            Map<String, EntityReference> result = new HashMap<>();
-            EntityState entityState = entityStateOf( (EntityComposite) entity );
-            final NamedAssociationState state = entityState.namedAssociationValueOf( associationDescriptor.qualifiedName() );
-            for( String name : state )
-            {
-                result.put( name, state.get( name ) );
-            }
-            return result;
-        }
-    }
-
-    private class ToEntityPropertyMappingFunction<T>
-        implements Function<PropertyDescriptor, Object>
-    {
-        private final T value;
-
-        public ToEntityPropertyMappingFunction( T value )
-        {
-            this.value = value;
-        }
-
-        @Override
-        public Object map( PropertyDescriptor propertyDescriptor )
-        {
-            StateHolder state = stateOf( (ValueComposite) value );
-            Property<Object> property = state.propertyFor( propertyDescriptor.accessor() );
-            return property.get();
-        }
-    }
-
-    private class ToEntityAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, EntityReference>
-    {
-
-        private final T value;
-
-        public ToEntityAssociationMappingFunction( T value )
-        {
-            this.value = value;
-        }
-
-        @Override
-        public EntityReference map( AssociationDescriptor associationDescriptor )
-        {
-            AssociationStateHolder state = stateOf( (ValueComposite) value );
-            AssociationInstance<T> association = (AssociationInstance<T>) state.associationFor( associationDescriptor.accessor() );
-            return association.getAssociationState().get();
-        }
-    }
-
-    private class ToEntityManyAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
-    {
-
-        private final T value;
-
-        public ToEntityManyAssociationMappingFunction( T value )
-        {
-            this.value = value;
-        }
-
-        @Override
-        public Iterable<EntityReference> map( AssociationDescriptor associationDescriptor )
-        {
-            AssociationStateHolder state = stateOf( (ValueComposite) value );
-            ManyAssociationInstance<T> association = (ManyAssociationInstance<T>) state.manyAssociationFor( associationDescriptor
-                                                                                                            .accessor() );
-            return association.getManyAssociationState();
-        }
-    }
-
-    private class ToEntityNameAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
-    {
-        private final T value;
-
-        public ToEntityNameAssociationMappingFunction( T value )
-        {
-            this.value = value;
-        }
-
-        @Override
-        public Map<String, EntityReference> map( AssociationDescriptor associationDescriptor )
-        {
-            AssociationStateHolder state = stateOf( (ValueComposite) value );
-            NamedAssociationInstance<T> association = (NamedAssociationInstance<T>) state.namedAssociationFor( associationDescriptor
-                                                                                                              .accessor() );
-            HashMap<String, EntityReference> result = new HashMap<>();
-            for( Map.Entry<String, EntityReference> entry : association.getEntityReferences() )
-            {
-                result.put( entry.getKey(), entry.getValue() );
-            }
-            return result;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/association/AbstractAssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/association/AbstractAssociationInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/association/AbstractAssociationInstance.java
index e42b2c5..e8de5c1 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/association/AbstractAssociationInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/association/AbstractAssociationInstance.java
@@ -1,14 +1,10 @@
 package org.qi4j.runtime.association;
 
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import org.qi4j.api.association.AbstractAssociation;
-import org.qi4j.api.entity.EntityComposite;
 import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
 import org.qi4j.functional.Function2;
-import org.qi4j.runtime.composite.ProxyReferenceInvocationHandler;
-import org.qi4j.runtime.entity.EntityInstance;
 
 /**
  * Implementation of AbstractAssociation. Includes helper methods for subclasses
@@ -55,32 +51,17 @@ public abstract class AbstractAssociationInstance<T>
             return null;
         }
 
-        InvocationHandler handler = Proxy.getInvocationHandler( composite );
-        if( handler instanceof ProxyReferenceInvocationHandler )
-        {
-            handler = Proxy.getInvocationHandler( ( (ProxyReferenceInvocationHandler) handler ).proxy() );
-        }
-        EntityInstance instance = (EntityInstance) handler;
-        return instance.identity();
+        return new EntityReference( ( (Identity) composite ).identity().get() );
     }
 
     protected void checkType( Object instance )
     {
-        if( instance != null )
-        {
-            if( !( instance instanceof EntityComposite ) )
-            {
-                if( instance instanceof Proxy )
-                {
-                    if( Proxy.getInvocationHandler( instance ) instanceof EntityInstance )
-                    {
-                        return; // It's fine
-                    }
-                }
 
-                throw new IllegalArgumentException( "Object must be an EntityComposite" );
-            }
+        if( instance instanceof Identity || instance == null )
+        {
+            return;
         }
+        throw new IllegalArgumentException( "Object must be a subtype of org.qi4j.api.identity.Identity" );
     }
 
     protected void checkImmutable()

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/association/AssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/association/AssociationInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/association/AssociationInstance.java
index d5babcd..e42d8eb 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/association/AssociationInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/association/AssociationInstance.java
@@ -19,6 +19,7 @@ import org.qi4j.api.association.Association;
 import org.qi4j.api.association.AssociationDescriptor;
 import org.qi4j.api.association.AssociationWrapper;
 import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
 import org.qi4j.api.property.Property;
 import org.qi4j.functional.Function2;
 
@@ -57,7 +58,13 @@ public final class AssociationInstance<T>
         associationInfo.checkConstraints( newValue );
 
         // Change association
-        associationState.set( getEntityReference( newValue ) );
+        associationState.set( EntityReference.create( (Identity) newValue ));
+    }
+
+    @Override
+    public EntityReference reference()
+    {
+        return associationState.get();
     }
 
     public Property<EntityReference> getAssociationState()
@@ -81,10 +88,10 @@ public final class AssociationInstance<T>
     @Override
     public int hashCode()
     {
-        int hash = associationInfo.hashCode() * 61; // Descriptor
+        int hash = associationInfo.hashCode() * 39; // Descriptor
         if( associationState.get() != null )
         {
-            hash += associationState.get().hashCode() * 3; // State
+            hash = hash * 997 + associationState.get().hashCode(); // State
         }
         return hash;
     }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/association/ManyAssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/association/ManyAssociationInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/association/ManyAssociationInstance.java
index a946862..eafda9a 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/association/ManyAssociationInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/association/ManyAssociationInstance.java
@@ -10,8 +10,10 @@ import org.qi4j.api.association.AssociationDescriptor;
 import org.qi4j.api.association.ManyAssociation;
 import org.qi4j.api.association.ManyAssociationWrapper;
 import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
+import org.qi4j.api.util.NullArgumentException;
 import org.qi4j.functional.Function2;
-import org.qi4j.runtime.composite.ConstraintsCheck;
+import org.qi4j.functional.Iterables;
 import org.qi4j.spi.entity.ManyAssociationState;
 
 /**
@@ -47,10 +49,11 @@ public class ManyAssociationInstance<T>
     @Override
     public boolean add( int i, T entity )
     {
+        NullArgumentException.validateNotNull( "entity", entity );
         checkImmutable();
         checkType( entity );
-        ( (ConstraintsCheck) associationInfo ).checkConstraints( entity );
-        return manyAssociationState.add( i, getEntityReference( entity ) );
+        associationInfo.checkConstraints( entity );
+        return manyAssociationState.add( i, new EntityReference( ( (Identity) entity ).identity().get() ) );
     }
 
     @Override
@@ -62,10 +65,11 @@ public class ManyAssociationInstance<T>
     @Override
     public boolean remove( T entity )
     {
+        NullArgumentException.validateNotNull( "entity", entity );
         checkImmutable();
         checkType( entity );
 
-        return manyAssociationState.remove( getEntityReference( entity ) );
+        return manyAssociationState.remove( new EntityReference( ( (Identity) entity ).identity().get() ) );
     }
 
     @Override
@@ -77,7 +81,7 @@ public class ManyAssociationInstance<T>
     @Override
     public List<T> toList()
     {
-        ArrayList<T> list = new ArrayList<T>();
+        ArrayList<T> list = new ArrayList<>();
         for( EntityReference entityReference : manyAssociationState )
         {
             list.add( getEntity( entityReference ) );
@@ -89,7 +93,7 @@ public class ManyAssociationInstance<T>
     @Override
     public Set<T> toSet()
     {
-        Set<T> set = new HashSet<T>();
+        Set<T> set = new HashSet<>();
         for( EntityReference entityReference : manyAssociationState )
         {
             set.add( getEntity( entityReference ) );
@@ -99,6 +103,12 @@ public class ManyAssociationInstance<T>
     }
 
     @Override
+    public Iterable<EntityReference> references()
+    {
+        return Iterables.toList( manyAssociationState );
+    }
+
+    @Override
     public String toString()
     {
         return manyAssociationState.toString();
@@ -194,15 +204,4 @@ public class ManyAssociationInstance<T>
             idIterator.remove();
         }
     }
-
-    @Override
-    protected void checkType( Object instance )
-    {
-        if( instance == null )
-        {
-            throw new NullPointerException( "Associated object may not be null" );
-        }
-
-        super.checkType( instance );
-    }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/association/NamedAssociationInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/association/NamedAssociationInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/association/NamedAssociationInstance.java
index 284de5d..7bffb4b 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/association/NamedAssociationInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/association/NamedAssociationInstance.java
@@ -24,12 +24,15 @@ import java.util.Iterator;
 import java.util.Map;
 import org.qi4j.api.association.NamedAssociation;
 import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
+import org.qi4j.api.util.NullArgumentException;
 import org.qi4j.functional.Function;
 import org.qi4j.functional.Function2;
 import org.qi4j.functional.Iterables;
-import org.qi4j.runtime.composite.ConstraintsCheck;
 import org.qi4j.spi.entity.NamedAssociationState;
 
+import static org.qi4j.functional.Iterables.map;
+
 public class NamedAssociationInstance<T>
     extends AbstractAssociationInstance<T>
     implements NamedAssociation<T>
@@ -39,7 +42,8 @@ public class NamedAssociationInstance<T>
 
     public NamedAssociationInstance( AssociationInfo associationInfo,
                                      Function2<EntityReference, Type, Object> associationFunction,
-                                     NamedAssociationState namedAssociationState )
+                                     NamedAssociationState namedAssociationState
+    )
     {
         super( associationInfo, associationFunction );
         this.namedAssociationState = namedAssociationState;
@@ -66,10 +70,11 @@ public class NamedAssociationInstance<T>
     @Override
     public boolean put( String name, T entity )
     {
+        NullArgumentException.validateNotNull( "entity", entity );
         checkImmutable();
         checkType( entity );
-        ( (ConstraintsCheck) associationInfo ).checkConstraints( entity );
-        return namedAssociationState.put( name, getEntityReference( entity ) );
+        associationInfo.checkConstraints( entity );
+        return namedAssociationState.put( name, new EntityReference( ( (Identity) entity ).identity().get() ) );
     }
 
     @Override
@@ -102,9 +107,22 @@ public class NamedAssociationInstance<T>
         return map;
     }
 
-    public Iterable<Map.Entry<String,EntityReference>> getEntityReferences()
+    @Override
+    public Iterable<EntityReference> references()
     {
-        return Iterables.map( new Function<String, Map.Entry<String,EntityReference>>()
+        return map( new Function<String, EntityReference>()
+        {
+            @Override
+            public EntityReference map( String name )
+            {
+                return namedAssociationState.get( name );
+            }
+        }, namedAssociationState );
+    }
+
+    public Iterable<Map.Entry<String, EntityReference>> getEntityReferences()
+    {
+        return map( new Function<String, Map.Entry<String, EntityReference>>()
         {
             @Override
             public Map.Entry<String, EntityReference> map( final String key )
@@ -133,10 +151,10 @@ public class NamedAssociationInstance<T>
                     @Override
                     public boolean equals( Object o )
                     {
-                        if( o instanceof Map.Entry)
+                        if( o instanceof Map.Entry )
                         {
                             Map.Entry other = (Map.Entry) o;
-                            return key.equals(other.getKey());
+                            return key.equals( other.getKey() );
                         }
                         return false;
                     }
@@ -150,5 +168,4 @@ public class NamedAssociationInstance<T>
             }
         }, namedAssociationState );
     }
-
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
index dd1a830..9f63d2c 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2009, Rickard Öberg. All Rights Reserved.
- * Copyright (c) 2013, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2013-2015, Niclas Hedhman. All Rights Reserved.
  * Copyright (c) 2013-2015, Paul Merlin. All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,9 +16,11 @@
 package org.qi4j.runtime.structure;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import org.qi4j.api.association.AssociationDescriptor;
+import org.qi4j.api.association.AssociationStateHolder;
 import org.qi4j.api.common.QualifiedName;
 import org.qi4j.api.composite.Composite;
 import org.qi4j.api.entity.EntityBuilder;
@@ -27,7 +29,9 @@ import org.qi4j.api.entity.EntityReference;
 import org.qi4j.api.entity.Identity;
 import org.qi4j.api.entity.IdentityGenerator;
 import org.qi4j.api.entity.LifecycleException;
+import org.qi4j.api.property.Property;
 import org.qi4j.api.property.PropertyDescriptor;
+import org.qi4j.api.property.StateHolder;
 import org.qi4j.api.query.Query;
 import org.qi4j.api.query.QueryBuilder;
 import org.qi4j.api.query.QueryExecutionException;
@@ -42,18 +46,24 @@ import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
 import org.qi4j.api.unitofwork.UnitOfWorkFactory;
 import org.qi4j.api.usecase.Usecase;
 import org.qi4j.api.util.NullArgumentException;
+import org.qi4j.api.value.ValueBuilder;
+import org.qi4j.api.value.ValueComposite;
 import org.qi4j.functional.Function;
 import org.qi4j.functional.Iterables;
 import org.qi4j.functional.Specification;
+import org.qi4j.runtime.association.AssociationInstance;
+import org.qi4j.runtime.association.ManyAssociationInstance;
+import org.qi4j.runtime.association.NamedAssociationInstance;
 import org.qi4j.runtime.composite.FunctionStateResolver;
 import org.qi4j.runtime.entity.EntityInstance;
 import org.qi4j.runtime.entity.EntityModel;
 import org.qi4j.runtime.property.PropertyModel;
 import org.qi4j.runtime.unitofwork.EntityBuilderInstance;
 import org.qi4j.runtime.unitofwork.UnitOfWorkInstance;
-import org.qi4j.runtime.composite.StateResolver;
-import org.qi4j.runtime.value.ValueStateModel;
+import org.qi4j.runtime.value.ValueInstance;
+import org.qi4j.spi.entity.EntityState;
 import org.qi4j.spi.entity.EntityStatus;
+import org.qi4j.spi.entity.NamedAssociationState;
 import org.qi4j.spi.entitystore.EntityStore;
 import org.qi4j.spi.query.EntityFinder;
 import org.qi4j.spi.query.EntityFinderException;
@@ -133,7 +143,7 @@ public class ModuleUnitOfWork
     }
 
     @Override
-    @SuppressWarnings( {"raw", "unchecked"} )
+    @SuppressWarnings( { "raw", "unchecked" } )
     public <T> Query<T> newQuery( QueryBuilder<T> queryBuilder )
     {
         QueryBuilderSPI queryBuilderSPI = (QueryBuilderSPI) queryBuilder;
@@ -235,7 +245,7 @@ public class ModuleUnitOfWork
 
         EntityStore entityStore = model.module().entityStore();
 
-        StateResolver stateResolver = new FunctionStateResolver(
+        FunctionStateResolver stateResolver = new FunctionStateResolver(
             propertyFunction, associationFunction, manyAssociationFunction, namedAssociationFunction
         );
 
@@ -314,6 +324,7 @@ public class ModuleUnitOfWork
         }
     }
 
+    @SuppressWarnings( "DuplicateThrows" )
     @Override
     public void complete()
         throws UnitOfWorkCompletionException, ConcurrentEntityModificationException
@@ -332,7 +343,7 @@ public class ModuleUnitOfWork
     {
         discard();
     }
-    
+
     @Override
     public boolean isOpen()
     {
@@ -403,6 +414,55 @@ public class ModuleUnitOfWork
         uow.addEntity( instance );
     }
 
+    @Override
+    public <T extends Identity> T toValue( Class<T> primaryType, T entityComposite )
+    {
+        Function<PropertyDescriptor, Object> propertyFunction = new ToValuePropertyMappingFunction( entityComposite );
+        Function<AssociationDescriptor, EntityReference> assocationFunction = new ToValueAssociationMappingFunction<>( entityComposite );
+        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssocFunction = new ToValueManyAssociationMappingFunction<>( entityComposite );
+        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssocFunction = new ToValueNameAssociationMappingFunction<>( entityComposite );
+
+        @SuppressWarnings( "unchecked" )
+        ValueBuilder<T> builder = module().newValueBuilderWithState(
+            primaryType, propertyFunction, assocationFunction, manyAssocFunction, namedAssocFunction );
+        return builder.newInstance();
+    }
+
+    @Override
+    public <T extends Identity> T toEntity( Class<T> primaryType, T valueComposite )
+    {
+        Function<PropertyDescriptor, Object> propertyFunction = new ToEntityPropertyMappingFunction<>( valueComposite );
+        Function<AssociationDescriptor, EntityReference> assocationFunction = new ToEntityAssociationMappingFunction<>( valueComposite );
+        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssocFunction = new ToEntityManyAssociationMappingFunction<>( valueComposite );
+        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssocFunction = new ToEntityNameAssociationMappingFunction<>( valueComposite );
+
+        String identity = valueComposite.identity().get();
+        try
+        {
+            T entity = get( primaryType, identity );
+            // If successful, then this entity is to by modified.
+            EntityInstance instance = EntityInstance.entityInstanceOf( (EntityComposite) entity );
+            EntityState state = instance.entityState();
+            FunctionStateResolver stateResolver = new FunctionStateResolver( propertyFunction,
+                                                                             assocationFunction,
+                                                                             manyAssocFunction,
+                                                                             namedAssocFunction );
+            EntityModel model = (EntityModel) EntityInstance.entityInstanceOf( (EntityComposite) entity ).descriptor();
+            stateResolver.populateState( model, state );
+            return entity;
+        }
+        catch( NoSuchEntityException e )
+        {
+            EntityBuilder<T> entityBuilder = newEntityBuilderWithState( primaryType,
+                                                                        identity,
+                                                                        propertyFunction,
+                                                                        assocationFunction,
+                                                                        manyAssocFunction,
+                                                                        namedAssocFunction );
+            return entityBuilder.newInstance();
+        }
+    }
+
     private static class UoWQuerySource implements QuerySource
     {
         private final ModuleUnitOfWork moduleUnitOfWork;
@@ -533,4 +593,167 @@ public class ModuleUnitOfWork
             return "UnitOfWork( " + moduleUnitOfWork.usecase().name() + " )";
         }
     }
+
+    private class ToValuePropertyMappingFunction
+        implements Function<PropertyDescriptor, Object>
+    {
+        private Object entity;
+
+        public ToValuePropertyMappingFunction( Object entity )
+        {
+            this.entity = entity;
+        }
+
+        @Override
+        public Object map( PropertyDescriptor propertyDescriptor )
+        {
+            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
+            return entityState.propertyValueOf( propertyDescriptor.qualifiedName() );
+        }
+    }
+
+    private class ToValueAssociationMappingFunction<T>
+        implements Function<AssociationDescriptor, EntityReference>
+    {
+        private final T entity;
+
+        public ToValueAssociationMappingFunction( T entity )
+        {
+            this.entity = entity;
+        }
+
+        @Override
+        public EntityReference map( AssociationDescriptor associationDescriptor )
+        {
+            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
+            return entityState.associationValueOf( associationDescriptor.qualifiedName() );
+        }
+    }
+
+    private class ToValueManyAssociationMappingFunction<T>
+        implements Function<AssociationDescriptor, Iterable<EntityReference>>
+    {
+        private final T entity;
+
+        public ToValueManyAssociationMappingFunction( T entity )
+        {
+            this.entity = entity;
+        }
+
+        @Override
+        public Iterable<EntityReference> map( AssociationDescriptor associationDescriptor )
+        {
+            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
+            return entityState.manyAssociationValueOf( associationDescriptor.qualifiedName() );
+        }
+    }
+
+    private class ToValueNameAssociationMappingFunction<T>
+        implements Function<AssociationDescriptor, Map<String, EntityReference>>
+    {
+        private final T entity;
+
+        public ToValueNameAssociationMappingFunction( T entity )
+        {
+            this.entity = entity;
+        }
+
+        @Override
+        public Map<String, EntityReference> map( AssociationDescriptor associationDescriptor )
+        {
+            Map<String, EntityReference> result = new HashMap<>();
+            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
+            final NamedAssociationState state = entityState.namedAssociationValueOf( associationDescriptor.qualifiedName() );
+            for( String name : state )
+            {
+                result.put( name, state.get( name ) );
+            }
+            return result;
+        }
+    }
+
+    private class ToEntityPropertyMappingFunction<T>
+        implements Function<PropertyDescriptor, Object>
+    {
+        private final T value;
+
+        public ToEntityPropertyMappingFunction( T value )
+        {
+            this.value = value;
+        }
+
+        @Override
+        public Object map( PropertyDescriptor propertyDescriptor )
+        {
+            StateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
+            Property<Object> property = state.propertyFor( propertyDescriptor.accessor() );
+            return property.get();
+        }
+    }
+
+    private class ToEntityAssociationMappingFunction<T>
+        implements Function<AssociationDescriptor, EntityReference>
+    {
+
+        private final T value;
+
+        public ToEntityAssociationMappingFunction( T value )
+        {
+            this.value = value;
+        }
+
+        @Override
+        public EntityReference map( AssociationDescriptor associationDescriptor )
+        {
+            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
+            AssociationInstance<T> association = (AssociationInstance<T>) state.associationFor( associationDescriptor.accessor() );
+            return association.getAssociationState().get();
+        }
+    }
+
+    private class ToEntityManyAssociationMappingFunction<T>
+        implements Function<AssociationDescriptor, Iterable<EntityReference>>
+    {
+
+        private final T value;
+
+        public ToEntityManyAssociationMappingFunction( T value )
+        {
+            this.value = value;
+        }
+
+        @Override
+        public Iterable<EntityReference> map( AssociationDescriptor associationDescriptor )
+        {
+            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
+            ManyAssociationInstance<T> association =
+                (ManyAssociationInstance<T>) state.manyAssociationFor( associationDescriptor.accessor() );
+            return association.getManyAssociationState();
+        }
+    }
+
+    private class ToEntityNameAssociationMappingFunction<T>
+        implements Function<AssociationDescriptor, Map<String, EntityReference>>
+    {
+        private final T value;
+
+        public ToEntityNameAssociationMappingFunction( T value )
+        {
+            this.value = value;
+        }
+
+        @Override
+        public Map<String, EntityReference> map( AssociationDescriptor associationDescriptor )
+        {
+            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
+            NamedAssociationInstance<T> association =
+                (NamedAssociationInstance<T>) state.namedAssociationFor( associationDescriptor.accessor() );
+            HashMap<String, EntityReference> result = new HashMap<>();
+            for( Map.Entry<String, EntityReference> entry : association.getEntityReferences() )
+            {
+                result.put( entry.getKey(), entry.getValue() );
+            }
+            return result;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
index 95c2e92..eae69b1 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
@@ -16,23 +16,16 @@
  */
 package org.qi4j.runtime.unitofwork;
 
-import java.util.Map;
-import org.qi4j.api.association.AssociationDescriptor;
 import org.qi4j.api.common.QualifiedName;
 import org.qi4j.api.entity.EntityBuilder;
 import org.qi4j.api.entity.EntityReference;
 import org.qi4j.api.entity.Identity;
 import org.qi4j.api.entity.LifecycleException;
-import org.qi4j.api.property.PropertyDescriptor;
-import org.qi4j.runtime.association.ManyAssociationModel;
-import org.qi4j.runtime.association.NamedAssociationModel;
 import org.qi4j.runtime.composite.FunctionStateResolver;
 import org.qi4j.runtime.entity.EntityInstance;
 import org.qi4j.runtime.entity.EntityModel;
 import org.qi4j.runtime.structure.ModelModule;
 import org.qi4j.runtime.structure.ModuleUnitOfWork;
-import org.qi4j.runtime.composite.StateResolver;
-import org.qi4j.runtime.value.ValueStateModel;
 import org.qi4j.spi.entity.EntityState;
 import org.qi4j.spi.entitystore.EntityStoreUnitOfWork;
 
@@ -80,7 +73,7 @@ public final class EntityBuilderInstance<T>
         ModuleUnitOfWork uow,
         EntityStoreUnitOfWork store,
         String identity,
-        StateResolver stateResolver
+        FunctionStateResolver stateResolver
     )
     {
         this.model = model;
@@ -92,7 +85,7 @@ public final class EntityBuilderInstance<T>
         model.model().initState( model.module(), entityState );
         if( stateResolver != null )
         {
-            (( FunctionStateResolver) stateResolver).populateState( model.model(), entityState );
+            stateResolver.populateState( model.model(), entityState );
         }
         entityState.setPropertyValue( IDENTITY_STATE_NAME, identity );
         prototypeInstance = model.model().newInstance( uow, model.module(), entityState );

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/runtime/src/test/java/org/qi4j/runtime/value/ValueWithAssociationTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/qi4j/runtime/value/ValueWithAssociationTest.java b/core/runtime/src/test/java/org/qi4j/runtime/value/ValueWithAssociationTest.java
index 5d699d5..4f6b375 100644
--- a/core/runtime/src/test/java/org/qi4j/runtime/value/ValueWithAssociationTest.java
+++ b/core/runtime/src/test/java/org/qi4j/runtime/value/ValueWithAssociationTest.java
@@ -33,6 +33,7 @@ public class ValueWithAssociationTest extends AbstractQi4jTest
     {
         module.entities( SimpleName.class );
         module.entities( DualFaced.class );
+        module.values( SimpleName.class );
         module.values( DualFaced.class );
         module.services( MemoryEntityStoreService.class );
         module.services( UuidIdentityGeneratorService.class );
@@ -61,7 +62,7 @@ public class ValueWithAssociationTest extends AbstractQi4jTest
             proto.namedSimples().put( "niclas", simpleEntity );
             DualFaced faced = builder2.newInstance();
             identity2 = faced.identity().get();
-            value = spi.toValue( DualFaced.class, faced );
+            value = uow.toValue( DualFaced.class, faced );
             assertThat( value.identity().get(), equalTo( identity2 ) );
             uow.complete();
         }
@@ -83,7 +84,7 @@ public class ValueWithAssociationTest extends AbstractQi4jTest
                             .next()
                             .getValue(), equalTo( EntityReference.parseEntityReference( identity1 ) ) );
 
-            DualFaced resurrected = spi.toEntity( DualFaced.class, value );
+            DualFaced resurrected = uow.toEntity( DualFaced.class, value );
             assertThat( resurrected.simple(), equalTo( entity.simple() ) );
             assertThat( resurrected.simples(), equalTo( entity.simples() ) );
             assertThat( resurrected.namedSimples(), equalTo( entity.namedSimples() ) );
@@ -101,7 +102,7 @@ public class ValueWithAssociationTest extends AbstractQi4jTest
 
         try (UnitOfWork uow = module.newUnitOfWork())
         {
-            spi.toEntity( DualFaced.class, value );
+            uow.toEntity( DualFaced.class, value );
             uow.complete();
         }
 
@@ -114,6 +115,52 @@ public class ValueWithAssociationTest extends AbstractQi4jTest
         }
     }
 
+    @Test
+    public void givenValueWithIdentityAlreadyInStoreWhenConvertingToEntityExpectExistingEntityToBeUpdated()
+        throws UnitOfWorkCompletionException
+    {
+        String identity1;
+        String identity2;
+        DualFaced value;
+        try (UnitOfWork uow = module.newUnitOfWork())
+        {
+            EntityBuilder<SimpleName> builder1 = uow.newEntityBuilder( SimpleName.class );
+            builder1.instance().name().set( "Niclas" );
+            SimpleName simpleEntity = builder1.newInstance();
+            identity1 = simpleEntity.identity().get();
+
+            EntityBuilder<DualFaced> builder2 = uow.newEntityBuilder( DualFaced.class );
+            DualFaced proto = builder2.instance();
+            proto.name().set( "Hedhman" );
+            proto.simple().set( simpleEntity );
+            proto.simples().add( simpleEntity );
+            proto.namedSimples().put( "niclas", simpleEntity );
+            DualFaced faced = builder2.newInstance();
+            identity2 = faced.identity().get();
+            uow.complete();
+        }
+        ValueBuilder<SimpleName> vb1 = module.newValueBuilder( SimpleName.class );
+        vb1.prototype().identity().set( identity1 );
+        vb1.prototype().name().set( "Paul" );
+        SimpleName simpleValue = vb1.newInstance();
+
+        ValueBuilder<DualFaced> vb2 = module.newValueBuilder( DualFaced.class );
+        vb2.prototype().identity().set(identity2);
+        vb2.prototype().name().set("Merlin");
+        vb2.prototype().simple().set( simpleValue );
+        vb2.prototype().simples().add( simpleValue );
+        vb2.prototype().namedSimples().put( "paul", simpleValue );
+        DualFaced dualValue = vb2.newInstance();
+
+        try (UnitOfWork uow = module.newUnitOfWork())
+        {
+            DualFaced dualEntity = uow.toEntity( DualFaced.class, dualValue );
+            assertThat( dualEntity.name().get(), equalTo( "Merlin"));
+            assertThat( dualEntity.simple().get().name().get(), equalTo( "Niclas"));
+            assertThat( dualEntity.simple().get().name().get(), equalTo( "Paul"));
+        }
+    }
+
     public interface SimpleName extends Identity
     {
         Property<String> name();

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
index 8b6246f..5345414 100644
--- a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
+++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
@@ -48,6 +48,7 @@ import org.qi4j.api.value.ValueSerializationException;
 import org.qi4j.api.value.ValueSerializer;
 import org.qi4j.functional.Function;
 import org.qi4j.functional.Function2;
+import org.qi4j.spi.Qi4jSPI;
 
 import static org.qi4j.functional.Iterables.first;
 
@@ -55,29 +56,29 @@ import static org.qi4j.functional.Iterables.first;
  * Adapter for pull-parsing capable ValueSerializers.
  *
  * <p>
- *     Among Plain values (see {@link ValueSerializer}) some are considered primitives to underlying serialization
- *     mechanisms and by so handed/come without conversion to/from implementations. Primitive values can be one of:
+ * Among Plain values (see {@link ValueSerializer}) some are considered primitives to underlying serialization
+ * mechanisms and by so handed/come without conversion to/from implementations. Primitive values can be one of:
  * </p>
  * <ul>
- *     <li>String,</li>
- *     <li>Character or char,</li>
- *     <li>Boolean or boolean,</li>
- *     <li>Integer or int,</li>
- *     <li>Long or long,</li>
- *     <li>Short or short,</li>
- *     <li>Byte or byte,</li>
- *     <li>Float or float,</li>
- *     <li>Double or double.</li>
+ * <li>String,</li>
+ * <li>Character or char,</li>
+ * <li>Boolean or boolean,</li>
+ * <li>Integer or int,</li>
+ * <li>Long or long,</li>
+ * <li>Short or short,</li>
+ * <li>Byte or byte,</li>
+ * <li>Float or float,</li>
+ * <li>Double or double.</li>
  * </ul>
  * <p>
- *     Some other Plain values are transformed before being handed to implementations:
+ * Some other Plain values are transformed before being handed to implementations:
  * </p>
  * <ul>
- *     <li>BigInteger and BigDecimal depends on ValueSerializer.{@link Options};</li>
- *     <li>Date as a ISO-8601 UTC String;</li>
- *     <li>DateTime (JodaTime) as a ISO-8601 String with timezone offset or Z for UTC;</li>
- *     <li>LocalDateTime (JodaTime) as a ISO-8601 String with no timezone offset;</li>
- *     <li>LocalDate (JodaTime) as a ISO-8601 String with no time info;</li>
+ * <li>BigInteger and BigDecimal depends on ValueSerializer.{@link Options};</li>
+ * <li>Date as a ISO-8601 UTC String;</li>
+ * <li>DateTime (JodaTime) as a ISO-8601 String with timezone offset or Z for UTC;</li>
+ * <li>LocalDateTime (JodaTime) as a ISO-8601 String with no timezone offset;</li>
+ * <li>LocalDate (JodaTime) as a ISO-8601 String with no time info;</li>
  * </ul>
  *
  * @param <OutputType> Implementor output type
@@ -112,8 +113,8 @@ public abstract class ValueSerializerAdapter<OutputType>
     /**
      * Register a Plain Value type serialization Function.
      *
-     * @param <T> Plain Value parametrized Type
-     * @param type Plain Value Type
+     * @param <T>        Plain Value parametrized Type
+     * @param type       Plain Value Type
      * @param serializer Serialization Function
      */
     @SuppressWarnings( "unchecked" )
@@ -125,8 +126,8 @@ public abstract class ValueSerializerAdapter<OutputType>
     /**
      * Register a Complex Value type serialization Function.
      *
-     * @param <T> Complex Value parametrized Type
-     * @param type Complex Value Type
+     * @param <T>        Complex Value parametrized Type
+     * @param type       Complex Value Type
      * @param serializer Serialization Function
      */
     @SuppressWarnings( "unchecked" )
@@ -364,48 +365,48 @@ public abstract class ValueSerializerAdapter<OutputType>
             onValue( output, null );
         }
         else // Registered serializer
-        if( serializers.get( object.getClass() ) != null )
-        {
-            onValue( output, serializers.get( object.getClass() ).map( options, object ) );
-        }
-        else if( complexSerializers.get( object.getClass() ) != null )
-        {
-            complexSerializers.get( object.getClass() ).serialize( options, object, output );
-        }
-        else // ValueComposite
-        if( ValueComposite.class.isAssignableFrom( object.getClass() ) )
-        {
-            serializeValueComposite( options, object, output, rootPass );
-        }
-        else // EntityComposite
-        if( EntityComposite.class.isAssignableFrom( object.getClass() ) )
-        {
-            serializeEntityComposite( object, output );
-        }
-        else // Collection - Iterable
-        if( Iterable.class.isAssignableFrom( object.getClass() ) )
-        {
-            serializeIterable( options, object, output );
-        }
-        else // Array - QUID Remove this and use java serialization for arrays?
-        if( object.getClass().isArray() )
-        {
-            serializeBase64Serializable( object, output );
-        }
-        else // Map
-        if( Map.class.isAssignableFrom( object.getClass() ) )
-        {
-            serializeMap( options, object, output );
-        }
-        else // Enum
-        if( object.getClass().isEnum() )
-        {
-            onValue( output, object.toString() );
-        }
-        else // Fallback to Base64 encoded Java Serialization
-        {
-            serializeBase64Serializable( object, output );
-        }
+            if( serializers.get( object.getClass() ) != null )
+            {
+                onValue( output, serializers.get( object.getClass() ).map( options, object ) );
+            }
+            else if( complexSerializers.get( object.getClass() ) != null )
+            {
+                complexSerializers.get( object.getClass() ).serialize( options, object, output );
+            }
+            else // ValueComposite
+                if( ValueComposite.class.isAssignableFrom( object.getClass() ) )
+                {
+                    serializeValueComposite( options, object, output, rootPass );
+                }
+                else // EntityComposite
+                    if( EntityComposite.class.isAssignableFrom( object.getClass() ) )
+                    {
+                        serializeEntityComposite( object, output );
+                    }
+                    else // Collection - Iterable
+                        if( Iterable.class.isAssignableFrom( object.getClass() ) )
+                        {
+                            serializeIterable( options, object, output );
+                        }
+                        else // Array - QUID Remove this and use java serialization for arrays?
+                            if( object.getClass().isArray() )
+                            {
+                                serializeBase64Serializable( object, output );
+                            }
+                            else // Map
+                                if( Map.class.isAssignableFrom( object.getClass() ) )
+                                {
+                                    serializeMap( options, object, output );
+                                }
+                                else // Enum
+                                    if( object.getClass().isEnum() )
+                                    {
+                                        onValue( output, object.toString() );
+                                    }
+                                    else // Fallback to Base64 encoded Java Serialization
+                                    {
+                                        serializeBase64Serializable( object, output );
+                                    }
     }
 
     private void serializeValueComposite( Options options, Object object, OutputType output, boolean rootPass )
@@ -548,7 +549,7 @@ public abstract class ValueSerializerAdapter<OutputType>
         throws Exception
     {
         ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        try( ObjectOutputStream out = new ObjectOutputStream( bout ) )
+        try (ObjectOutputStream out = new ObjectOutputStream( bout ))
         {
             out.writeUnshared( object );
         }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundAssociation.java
----------------------------------------------------------------------
diff --git a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundAssociation.java b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundAssociation.java
index 5c0daf0..b927cc3 100644
--- a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundAssociation.java
+++ b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundAssociation.java
@@ -18,6 +18,7 @@
 package org.qi4j.lib.swing.binding.internal;
 
 import org.qi4j.api.association.Association;
+import org.qi4j.api.entity.EntityReference;
 import org.qi4j.api.injection.scope.Service;
 import org.qi4j.api.injection.scope.Structure;
 import org.qi4j.api.injection.scope.Uses;
@@ -82,4 +83,10 @@ public final class BoundAssociation<T> extends AbstractBinding<T>
     {
         //To change body of implemented methods use File | Settings | File Templates.
     }
+
+    @Override
+    public EntityReference reference()
+    {
+        return actual.reference();
+    }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundManyAssociation.java
----------------------------------------------------------------------
diff --git a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundManyAssociation.java b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundManyAssociation.java
index a7dcb0f..892a3d5 100644
--- a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundManyAssociation.java
+++ b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundManyAssociation.java
@@ -5,6 +5,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.entity.EntityReference;
 import org.qi4j.api.injection.scope.Service;
 import org.qi4j.api.injection.scope.Structure;
 import org.qi4j.api.injection.scope.Uses;
@@ -59,6 +60,12 @@ public class BoundManyAssociation<T> extends AbstractBinding<T>
     }
 
     @Override
+    public Iterable<EntityReference> references()
+    {
+        return actualAssociations.references();
+    }
+
+    @Override
     public int count()
     {
         return actualAssociations.count();

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundNamedAssociation.java
----------------------------------------------------------------------
diff --git a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundNamedAssociation.java b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundNamedAssociation.java
index 8e9f187..7becd24 100644
--- a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundNamedAssociation.java
+++ b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundNamedAssociation.java
@@ -4,6 +4,7 @@ import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.Map;
 import org.qi4j.api.association.NamedAssociation;
+import org.qi4j.api.entity.EntityReference;
 import org.qi4j.api.injection.scope.Service;
 import org.qi4j.api.injection.scope.Structure;
 import org.qi4j.api.injection.scope.Uses;
@@ -75,6 +76,12 @@ public class BoundNamedAssociation<T>
     }
 
     @Override
+    public Iterable<EntityReference> references()
+    {
+        return actualAssociations.references();
+    }
+
+    @Override
     public Iterator<String> iterator()
     {
         return actualAssociations.iterator();

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/568fa2ff/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundProperty.java
----------------------------------------------------------------------
diff --git a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundProperty.java b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundProperty.java
index 30a88d6..7d22b44 100644
--- a/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundProperty.java
+++ b/samples/swing/src/main/java/org/qi4j/lib/swing/binding/internal/BoundProperty.java
@@ -17,19 +17,17 @@
  */
 package org.qi4j.lib.swing.binding.internal;
 
+import java.awt.event.FocusListener;
+import java.lang.reflect.Method;
+import javax.swing.JComponent;
 import org.qi4j.api.injection.scope.Service;
 import org.qi4j.api.injection.scope.Structure;
 import org.qi4j.api.injection.scope.Uses;
 import org.qi4j.api.object.ObjectFactory;
-import org.qi4j.api.property.GenericPropertyInfo;
 import org.qi4j.api.property.Property;
 import org.qi4j.lib.swing.binding.Binding;
 import org.qi4j.lib.swing.binding.SwingAdapter;
 
-import javax.swing.*;
-import java.awt.event.FocusListener;
-import java.lang.reflect.Method;
-
 public final class BoundProperty<T> extends AbstractBinding<T>
     implements Property<T>, Binding
 {
@@ -44,7 +42,8 @@ public final class BoundProperty<T> extends AbstractBinding<T>
      * @throws IllegalArgumentException Thrown if the specified {@code aMethod} is {@code null}.
      */
     public BoundProperty( @Uses Method propertyMethod, @Structure ObjectFactory objectBuilderFactory,
-                          @Service Iterable<SwingAdapter> allAdapters )
+                          @Service Iterable<SwingAdapter> allAdapters
+    )
         throws IllegalArgumentException
     {
         super( propertyMethod, objectBuilderFactory, allAdapters );


Mime
View raw message