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

[13/13] zest-java git commit: core: unify value creation shallow copying

core: unify value creation shallow copying

State shallow copying on value creation was spread across
- ValueBuilderWithPrototype
- StateResolver & various FunctionStateResolvers

It\u2019s now done on ValueStateInstance creation only

StateResolver now only returns Streams. Using Streams all along the way
allowed to remove duplicate shallow copying and make things more clean.

Added a few stream helpers to deal with Maps, used for NamedAssociation


Project: http://git-wip-us.apache.org/repos/asf/zest-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-java/commit/8854b130
Tree: http://git-wip-us.apache.org/repos/asf/zest-java/tree/8854b130
Diff: http://git-wip-us.apache.org/repos/asf/zest-java/diff/8854b130

Branch: refs/heads/develop
Commit: 8854b130634569c8a3ccae2efcc30fe3c3079c5c
Parents: 516f005
Author: Paul Merlin <pa...@apache.org>
Authored: Fri Dec 9 00:40:52 2016 +0100
Committer: Paul Merlin <pa...@apache.org>
Committed: Fri Dec 9 00:40:52 2016 +0100

----------------------------------------------------------------------
 .../zest/api/association/ManyAssociation.java   |  5 +-
 .../api/association/ManyAssociationWrapper.java |  3 +-
 .../zest/api/association/NamedAssociation.java  |  5 +-
 .../association/NamedAssociationWrapper.java    |  3 +-
 .../apache/zest/api/unitofwork/UnitOfWork.java  |  9 ++-
 .../org/apache/zest/api/util/Collectors.java    | 63 +++++++++++++--
 .../zest/api/value/ValueBuilderFactory.java     |  5 +-
 .../apache/zest/api/util/CollectorsTest.java    | 29 ++++---
 .../apache/zest/runtime/ZestRuntimeImpl.java    | 18 ++---
 .../association/ManyAssociationInstance.java    |  7 +-
 .../association/NamedAssociationInstance.java   |  7 +-
 .../composite/FunctionStateResolver.java        | 80 +++++++++-----------
 .../zest/runtime/composite/StateResolver.java   |  6 +-
 .../zest/runtime/structure/ModuleInstance.java  | 12 +--
 .../BuilderNamedAssociationState.java           |  4 +-
 .../runtime/unitofwork/ModuleUnitOfWork.java    | 63 ++++++---------
 .../value/ValueBuilderWithPrototype.java        | 36 ++-------
 .../zest/runtime/value/ValueStateInstance.java  | 15 ++--
 .../entity/EntityBuilderWithStateTest.java      | 12 +--
 .../runtime/value/ValueWithAssociationTest.java |  4 +-
 .../main/java/org/apache/zest/spi/ZestSPI.java  | 12 +--
 .../zest/spi/entity/ManyAssociationState.java   |  6 ++
 .../zest/spi/entity/NamedAssociationState.java  | 10 +++
 .../spi/value/ValueDeserializerAdapter.java     | 10 ++-
 .../zest/spi/value/ValueSerializerAdapter.java  |  5 +-
 .../requestreader/DefaultRequestReader.java     | 15 ++--
 .../binding/internal/BoundManyAssociation.java  |  3 +-
 .../binding/internal/BoundNamedAssociation.java |  3 +-
 28 files changed, 241 insertions(+), 209 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java
index 78c0ff9..0283d62 100644
--- a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java
+++ b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociation.java
@@ -22,6 +22,7 @@ package org.apache.zest.api.association;
 
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Stream;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
@@ -50,8 +51,8 @@ public interface ManyAssociation<T> extends Iterable<T>, AbstractAssociation
     Set<T> toSet();
 
     /**
-     * Returns an unmodifiable Iterable of the references to the associated entities.
+     * Returns a stream of the references to the associated entities.
      * @return the references to the associated entities.
      */
-    Iterable<EntityReference> references();
+    Stream<EntityReference> references();
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java
index e9e5a10..eda0fd7 100644
--- a/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java
+++ b/core/api/src/main/java/org/apache/zest/api/association/ManyAssociationWrapper.java
@@ -22,6 +22,7 @@ package org.apache.zest.api.association;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Stream;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
@@ -93,7 +94,7 @@ public class ManyAssociationWrapper
     }
 
     @Override
-    public Iterable<EntityReference> references()
+    public Stream<EntityReference> references()
     {
         return next.references();
     }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java
index fa61948..aced892 100644
--- a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java
+++ b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociation.java
@@ -20,6 +20,7 @@
 package org.apache.zest.api.association;
 
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
@@ -78,10 +79,10 @@ public interface NamedAssociation<T>
     Map<String, T> toMap();
 
     /**
-     * Returns an unmodifiable Iterable of the references to the associated entities.
+     * Returns a stream of the references to the associated entities.
      * @return the references to the associated entities.
      */
-    Iterable<EntityReference> references();
+    Stream<Map.Entry<String, EntityReference>> references();
 
     /** Returns the EntityReference for the Association with the given name.
      *

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java
index 42ee180..d67dbbf 100644
--- a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java
+++ b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java
@@ -21,6 +21,7 @@ package org.apache.zest.api.association;
 
 import java.util.Iterator;
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
@@ -92,7 +93,7 @@ public class NamedAssociationWrapper
     }
 
     @Override
-    public Iterable<EntityReference> references()
+    public Stream<Map.Entry<String, EntityReference>> references()
     {
         return next.references();
     }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/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 b8c2338..844562c 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
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.ManyAssociation;
 import org.apache.zest.api.association.NamedAssociation;
@@ -217,8 +218,8 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
     <T> EntityBuilder<T> newEntityBuilderWithState( Class<T> type,
                                                     Function<PropertyDescriptor, Object> propertyFunction,
                                                     Function<AssociationDescriptor, EntityReference> associationFunction,
-                                                    Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-                                                    Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+                                                    Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+                                                    Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction
     )
         throws NoSuchEntityTypeException, AmbiguousTypeException;
 
@@ -245,8 +246,8 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
     <T> EntityBuilder<T> newEntityBuilderWithState( Class<T> type, @Optional Identity identity,
                                                     Function<PropertyDescriptor, Object> propertyFunction,
                                                     Function<AssociationDescriptor, EntityReference> associationFunction,
-                                                    Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-                                                    Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+                                                    Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+                                                    Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction
     )
         throws NoSuchEntityTypeException, AmbiguousTypeException;
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/main/java/org/apache/zest/api/util/Collectors.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/util/Collectors.java b/core/api/src/main/java/org/apache/zest/api/util/Collectors.java
index c977059..d77bc0d 100644
--- a/core/api/src/main/java/org/apache/zest/api/util/Collectors.java
+++ b/core/api/src/main/java/org/apache/zest/api/util/Collectors.java
@@ -17,7 +17,10 @@
  */
 package org.apache.zest.api.util;
 
+import java.util.Map;
 import java.util.Optional;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collector;
 
@@ -29,25 +32,73 @@ public class Collectors
      * @return The single element
      * @throws IllegalArgumentException if no or more than one element
      */
-    public static <T> Collector<T, ?, T> single()
+    public static <T>
+    Collector<T, ?, T> single()
         throws IllegalArgumentException
     {
         Supplier<T> thrower = () ->
         {
             throw new IllegalArgumentException( "No or more than one element in stream" );
         };
-        return java.util.stream.Collectors.collectingAndThen( singleOrEmpty(),
+        return java.util.stream.Collectors.collectingAndThen( java.util.stream.Collectors.reducing( ( a, b ) -> null ),
                                                               optional -> optional.orElseGet( thrower ) );
     }
 
     /**
-     * Collect an optional single element.
+     * Eventually collect a single element.
      * @param <T> Element type
-     * @return An optional single element, empty if no or more than one element
+     * @return The single element, optional
+     * @throws IllegalArgumentException if more than one element
      */
-    public static <T> Collector<T, ?, Optional<T>> singleOrEmpty()
+    public static <T>
+    Collector<T, ?, Optional<T>> singleOrEmpty()
+        throws IllegalArgumentException
+    {
+        return java.util.stream.Collectors.reducing(
+            ( left, right ) ->
+            {
+                if( left != null && right != null )
+                {
+                    throw new IllegalArgumentException( "More than one element in stream" );
+                }
+                if( left != null )
+                {
+                    return left;
+                }
+                return right;
+            } );
+    }
+
+    public static <T, K, U, M extends Map<K, U>>
+    Collector<T, ?, M> toMap( Function<? super T, ? extends K> keyMapper,
+                              Function<? super T, ? extends U> valueMapper,
+                              Supplier<M> mapSupplier )
+    {
+        return java.util.stream.Collectors.toMap( keyMapper,
+                                                  valueMapper,
+                                                  throwingMerger(),
+                                                  mapSupplier );
+    }
+
+
+    public static <T extends Map.Entry<K, U>, K, U>
+    Collector<T, ?, Map<K, U>> toMap()
     {
-        return java.util.stream.Collectors.reducing( ( a, b ) -> null );
+        return java.util.stream.Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue );
+    }
+
+    public static <T extends Map.Entry<K, U>, K, U, M extends Map<K, U>>
+    Collector<T, ?, M> toMap( Supplier<M> mapSupplier )
+    {
+        return toMap( Map.Entry::getKey, Map.Entry::getValue, mapSupplier );
+    }
+
+    private static <T> BinaryOperator<T> throwingMerger()
+    {
+        return ( left, right ) ->
+        {
+            throw new IllegalStateException( String.format( "Duplicate key %s", left ) );
+        };
     }
 
     private Collectors() {}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/main/java/org/apache/zest/api/value/ValueBuilderFactory.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/value/ValueBuilderFactory.java b/core/api/src/main/java/org/apache/zest/api/value/ValueBuilderFactory.java
index 040f3d4..3a61b1a 100644
--- a/core/api/src/main/java/org/apache/zest/api/value/ValueBuilderFactory.java
+++ b/core/api/src/main/java/org/apache/zest/api/value/ValueBuilderFactory.java
@@ -21,6 +21,7 @@ package org.apache.zest.api.value;
 
 import java.util.Map;
 import java.util.function.Function;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.common.ConstructionException;
 import org.apache.zest.api.entity.EntityReference;
@@ -87,8 +88,8 @@ public interface ValueBuilderFactory
     <T> ValueBuilder<T> newValueBuilderWithState( Class<T> mixinType,
                                                   Function<PropertyDescriptor, Object> propertyFunction,
                                                   Function<AssociationDescriptor, EntityReference> associationFunction,
-                                                  Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-                                                  Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction );
+                                                  Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+                                                  Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction );
 
     /**
      * Instantiate a Value of the given type using the serialized state given as String.

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/api/src/test/java/org/apache/zest/api/util/CollectorsTest.java
----------------------------------------------------------------------
diff --git a/core/api/src/test/java/org/apache/zest/api/util/CollectorsTest.java b/core/api/src/test/java/org/apache/zest/api/util/CollectorsTest.java
index 6aeb871..7d9ade2 100644
--- a/core/api/src/test/java/org/apache/zest/api/util/CollectorsTest.java
+++ b/core/api/src/test/java/org/apache/zest/api/util/CollectorsTest.java
@@ -29,15 +29,6 @@ import static org.junit.Assert.fail;
 public class CollectorsTest
 {
     @Test
-    public void singleOrEmpty()
-    {
-        assertEquals( Optional.empty(), Stream.of().collect( Collectors.singleOrEmpty() ) );
-        assertEquals( Optional.of( 1 ), Stream.of( 1 ).collect( Collectors.singleOrEmpty() ) );
-        assertEquals( Optional.empty(), Stream.of( 1, 1 ).collect( Collectors.singleOrEmpty() ) );
-        assertEquals( Optional.empty(), Stream.of( 1, 1, 1 ).collect( Collectors.singleOrEmpty() ) );
-    }
-
-    @Test
     public void single()
     {
         assertThat( Stream.of( 1L ).collect( Collectors.single() ), is( 1L ) );
@@ -61,4 +52,24 @@ public class CollectorsTest
         }
         catch( IllegalArgumentException ex ) {}
     }
+
+    @Test
+    public void singleOrEmpty()
+    {
+        assertEquals( Optional.empty(), Stream.of().collect( Collectors.singleOrEmpty() ) );
+        assertEquals( Optional.of( 1 ), Stream.of( 1 ).collect( Collectors.singleOrEmpty() ) );
+
+        try
+        {
+            Stream.of( 1, 1 ).collect( Collectors.singleOrEmpty() );
+            fail( "Should have failed" );
+        }
+        catch( IllegalArgumentException ex ) {}
+        try
+        {
+            Stream.of( 1, 1, 1 ).collect( Collectors.singleOrEmpty() );
+            fail( "Should have failed" );
+        }
+        catch( IllegalArgumentException ex ) {}
+    }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
index 46531e1..d705546 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
@@ -22,6 +22,7 @@ package org.apache.zest.runtime;
 import java.lang.reflect.InvocationHandler;
 import java.util.Arrays;
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.zest.api.ZestAPI;
 import org.apache.zest.api.association.AbstractAssociation;
 import org.apache.zest.api.association.Association;
@@ -56,9 +57,6 @@ import org.apache.zest.bootstrap.ApplicationAssemblyFactory;
 import org.apache.zest.bootstrap.ApplicationModelFactory;
 import org.apache.zest.bootstrap.ZestRuntime;
 import org.apache.zest.runtime.association.AbstractAssociationInstance;
-import org.apache.zest.runtime.association.AssociationInstance;
-import org.apache.zest.runtime.association.ManyAssociationInstance;
-import org.apache.zest.runtime.association.NamedAssociationInstance;
 import org.apache.zest.runtime.bootstrap.ApplicationAssemblyFactoryImpl;
 import org.apache.zest.runtime.bootstrap.ApplicationModelFactoryImpl;
 import org.apache.zest.runtime.composite.ProxyReferenceInvocationHandler;
@@ -343,22 +341,20 @@ public final class ZestRuntimeImpl
     }
 
     @Override
-    public EntityReference entityReferenceOf( Association assoc )
+    public EntityReference entityReferenceOf( Association<?> assoc )
     {
-        @SuppressWarnings( "unchecked" )
-        Property<EntityReference> associationState = ( (AssociationInstance) assoc ).getAssociationState();
-        return associationState.get();
+        return assoc.reference();
     }
 
     @Override
-    public Iterable<EntityReference> entityReferenceOf( ManyAssociation assoc )
+    public Stream<EntityReference> entityReferencesOf( ManyAssociation<?> assoc )
     {
-        return ( (ManyAssociationInstance) assoc ).getManyAssociationState();
+        return assoc.references();
     }
 
     @Override
-    public Iterable<Map.Entry<String, EntityReference>> entityReferenceOf( NamedAssociation assoc )
+    public Stream<Map.Entry<String, EntityReference>> entityReferencesOf( NamedAssociation<?> assoc )
     {
-        return ( (NamedAssociationInstance) assoc ).getEntityReferences();
+        return assoc.references();
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/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 1d21029..6a50ee9 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
@@ -26,8 +26,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.function.BiFunction;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.ManyAssociation;
 import org.apache.zest.api.association.ManyAssociationWrapper;
@@ -123,9 +122,9 @@ public class ManyAssociationInstance<T>
     }
 
     @Override
-    public Iterable<EntityReference> references()
+    public Stream<EntityReference> references()
     {
-        return StreamSupport.stream( manyAssociationState.spliterator(), false ).collect( Collectors.toList() );
+        return manyAssociationState.stream();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/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 147fcc2..27e2826 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
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.NamedAssociation;
@@ -111,11 +112,9 @@ public class NamedAssociationInstance<T>
     }
 
     @Override
-    public Iterable<EntityReference> references()
+    public Stream<Map.Entry<String, EntityReference>> references()
     {
-        return StreamSupport.stream( namedAssociationState.spliterator(), false )
-                            .map( namedAssociationState::get )
-                            .collect( Collectors.toList() );
+        return namedAssociationState.stream();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/composite/FunctionStateResolver.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/composite/FunctionStateResolver.java b/core/runtime/src/main/java/org/apache/zest/runtime/composite/FunctionStateResolver.java
index 73bc4a8..10ceeed 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/composite/FunctionStateResolver.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/composite/FunctionStateResolver.java
@@ -19,9 +19,9 @@
  */
 package org.apache.zest.runtime.composite;
 
-import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.property.PropertyDescriptor;
@@ -30,9 +30,6 @@ import org.apache.zest.spi.entity.EntityState;
 import org.apache.zest.spi.entity.ManyAssociationState;
 import org.apache.zest.spi.entity.NamedAssociationState;
 
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.StreamSupport.stream;
-
 /**
  * Function based StateResolver.
  */
@@ -41,13 +38,13 @@ public class FunctionStateResolver
 {
     final Function<PropertyDescriptor, Object> propertyFunction;
     final Function<AssociationDescriptor, EntityReference> associationFunction;
-    final Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction;
-    final Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction;
+    final Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction;
+    final Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction;
 
     public FunctionStateResolver( Function<PropertyDescriptor, Object> propertyFunction,
                                   Function<AssociationDescriptor, EntityReference> associationFunction,
-                                  Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-                                  Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction )
+                                  Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+                                  Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction )
     {
         this.propertyFunction = propertyFunction;
         this.associationFunction = associationFunction;
@@ -68,54 +65,51 @@ public class FunctionStateResolver
     }
 
     @Override
-    public List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
+    public Stream<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
     {
-        // FIXME Do not shallow copy here
-        return stream( manyAssociationFunction.apply( associationDescriptor ).spliterator(), false )
-            .collect( toList() );
+        return manyAssociationFunction.apply( associationDescriptor );
     }
 
     @Override
-    public Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor )
+    public Stream<Map.Entry<String, EntityReference>> getNamedAssociationState(
+        AssociationDescriptor associationDescriptor )
     {
         return namedAssociationFunction.apply( associationDescriptor );
     }
 
     public void populateState( EntityModel model, EntityState state )
     {
-        model.state().properties().forEach( propDesc -> {
-            Object value = getPropertyState( propDesc );
-            state.setPropertyValue( propDesc.qualifiedName(), value );
-        } );
-        model.state().associations().forEach( assDesc -> {
-            EntityReference ref = getAssociationState( assDesc );
-            state.setAssociationValue( assDesc.qualifiedName(), ref );
-        } );
-        model.state().manyAssociations().forEach( manyAssDesc -> {
-            ManyAssociationState associationState = state.manyAssociationValueOf( manyAssDesc.qualifiedName() );
-            // First clear existing ones
-            for( EntityReference ref : associationState )
+        model.state().properties().forEach(
+            propDesc ->
             {
-                associationState.remove( ref );
-            }
-            // then add the new ones.
-            for( EntityReference ref : getManyAssociationState( manyAssDesc ) )
+                Object value = getPropertyState( propDesc );
+                state.setPropertyValue( propDesc.qualifiedName(), value );
+            } );
+        model.state().associations().forEach(
+            assDesc ->
             {
-                associationState.add( 0, ref );
-            }
-        } );
-        model.state().namedAssociations().forEach( namedAssDesc -> {
-            NamedAssociationState associationState = state.namedAssociationValueOf( namedAssDesc.qualifiedName() );
-            // First clear existing ones
-            for( String name : associationState )
+                EntityReference ref = getAssociationState( assDesc );
+                state.setAssociationValue( assDesc.qualifiedName(), ref );
+            } );
+        model.state().manyAssociations().forEach(
+            manyAssDesc ->
             {
-                associationState.remove( name );
-            }
-            // then add the new ones.
-            for( Map.Entry<String, EntityReference> entry : getNamedAssociationState( namedAssDesc ).entrySet() )
+                ManyAssociationState associationState = state.manyAssociationValueOf( manyAssDesc.qualifiedName() );
+                // First clear existing ones
+                associationState.forEach( associationState::remove );
+                // then add the new ones.
+                getManyAssociationState( manyAssDesc )
+                    .forEach( ref -> associationState.add( 0, ref ) );
+            } );
+        model.state().namedAssociations().forEach(
+            namedAssDesc ->
             {
-                associationState.put( entry.getKey(), entry.getValue() );
-            }
-        } );
+                NamedAssociationState associationState = state.namedAssociationValueOf( namedAssDesc.qualifiedName() );
+                // First clear existing ones
+                associationState.forEach( associationState::remove );
+                // then add the new ones.
+                getNamedAssociationState( namedAssDesc )
+                    .forEach( entry -> associationState.put( entry.getKey(), entry.getValue() ) );
+            } );
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/composite/StateResolver.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/composite/StateResolver.java b/core/runtime/src/main/java/org/apache/zest/runtime/composite/StateResolver.java
index 129a27b..0e7408b 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/composite/StateResolver.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/composite/StateResolver.java
@@ -19,8 +19,8 @@
  */
 package org.apache.zest.runtime.composite;
 
-import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.property.PropertyDescriptor;
@@ -34,7 +34,7 @@ public interface StateResolver
 
     EntityReference getAssociationState( AssociationDescriptor associationDescriptor );
 
-    List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor );
+    Stream<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor );
 
-    Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor );
+    Stream<Map.Entry<String, EntityReference>> getNamedAssociationState( AssociationDescriptor associationDescriptor );
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
index 7a8a72d..b101716 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
@@ -261,8 +261,8 @@ public class ModuleInstance
     public <T> ValueBuilder<T> newValueBuilderWithState( Class<T> mixinType,
                                                          Function<PropertyDescriptor, Object> propertyFunction,
                                                          Function<AssociationDescriptor, EntityReference> associationFunction,
-                                                         Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-                                                         Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+                                                         Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+                                                         Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction
     )
     {
         NullArgumentException.validateNotNull( "propertyFunction", propertyFunction );
@@ -306,15 +306,15 @@ public class ModuleInstance
         }
 
         @Override
-        public List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
+        public Stream<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
         {
-            return new ArrayList<>();
+            return new ArrayList<EntityReference>().stream();
         }
 
         @Override
-        public Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor )
+        public Stream<Map.Entry<String, EntityReference>> getNamedAssociationState( AssociationDescriptor associationDescriptor )
         {
-            return new HashMap<>();
+            return new HashMap<String, EntityReference>().entrySet().stream();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java
index 932388f..fc02340 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java
@@ -19,8 +19,8 @@
  */
 package org.apache.zest.runtime.unitofwork;
 
-import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.spi.entity.NamedAssociationState;
@@ -36,7 +36,7 @@ public final class BuilderNamedAssociationState
 
     public BuilderNamedAssociationState()
     {
-        references = new HashMap<>();
+        references = new LinkedHashMap<>();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/ModuleUnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/ModuleUnitOfWork.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/ModuleUnitOfWork.java
index 4f22d69..19fea5d 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/ModuleUnitOfWork.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/ModuleUnitOfWork.java
@@ -22,7 +22,6 @@ package org.apache.zest.runtime.unitofwork;
 
 import java.time.Instant;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -69,8 +68,6 @@ import org.apache.zest.api.util.NullArgumentException;
 import org.apache.zest.api.value.ValueBuilder;
 import org.apache.zest.api.value.ValueComposite;
 import org.apache.zest.runtime.association.AssociationInstance;
-import org.apache.zest.runtime.association.ManyAssociationInstance;
-import org.apache.zest.runtime.association.NamedAssociationInstance;
 import org.apache.zest.runtime.composite.FunctionStateResolver;
 import org.apache.zest.runtime.entity.EntityInstance;
 import org.apache.zest.runtime.entity.EntityModel;
@@ -78,7 +75,6 @@ import org.apache.zest.runtime.property.PropertyModel;
 import org.apache.zest.runtime.value.ValueInstance;
 import org.apache.zest.spi.entity.EntityState;
 import org.apache.zest.spi.entity.EntityStatus;
-import org.apache.zest.spi.entity.NamedAssociationState;
 import org.apache.zest.spi.entitystore.EntityStore;
 import org.apache.zest.spi.module.ModuleSpi;
 import org.apache.zest.spi.query.EntityFinder;
@@ -215,8 +211,8 @@ public class ModuleUnitOfWork
         Class<T> type,
         Function<PropertyDescriptor, Object> propertyFunction,
         Function<AssociationDescriptor, EntityReference> associationFunction,
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+        Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+        Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction
     )
         throws NoSuchEntityTypeException
     {
@@ -232,8 +228,8 @@ public class ModuleUnitOfWork
         Class<T> type, Identity identity,
         Function<PropertyDescriptor, Object> propertyFunction,
         Function<AssociationDescriptor, EntityReference> associationFunction,
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+        Function<AssociationDescriptor, Stream<EntityReference>> manyAssociationFunction,
+        Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssociationFunction
     )
         throws NoSuchEntityTypeException
     {
@@ -434,8 +430,8 @@ public class ModuleUnitOfWork
     {
         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 );
+        Function<AssociationDescriptor, Stream<EntityReference>> manyAssocFunction = new ToValueManyAssociationMappingFunction<>( entityComposite );
+        Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssocFunction = new ToValueNameAssociationMappingFunction<>( entityComposite );
 
         @SuppressWarnings( "unchecked" )
         ValueBuilder<T> builder = module().instance().newValueBuilderWithState(
@@ -487,8 +483,8 @@ public class ModuleUnitOfWork
     {
         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 );
+        Function<AssociationDescriptor, Stream<EntityReference>> manyAssocFunction = new ToEntityManyAssociationMappingFunction<>( valueComposite );
+        Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>> namedAssocFunction = new ToEntityNameAssociationMappingFunction<>( valueComposite );
 
         try
         {
@@ -660,7 +656,7 @@ public class ModuleUnitOfWork
     }
 
     private class ToValueManyAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
+        implements Function<AssociationDescriptor, Stream<EntityReference>>
     {
         private final T entity;
 
@@ -670,15 +666,15 @@ public class ModuleUnitOfWork
         }
 
         @Override
-        public Iterable<EntityReference> apply( AssociationDescriptor associationDescriptor )
+        public Stream<EntityReference> apply( AssociationDescriptor associationDescriptor )
         {
             EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
-            return entityState.manyAssociationValueOf( associationDescriptor.qualifiedName() );
+            return entityState.manyAssociationValueOf( associationDescriptor.qualifiedName() ).stream();
         }
     }
 
     private class ToValueNameAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
+        implements Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>>
     {
         private final T entity;
 
@@ -688,16 +684,10 @@ public class ModuleUnitOfWork
         }
 
         @Override
-        public Map<String, EntityReference> apply( AssociationDescriptor associationDescriptor )
+        public Stream<Map.Entry<String, EntityReference>> apply( 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;
+            return entityState.namedAssociationValueOf( associationDescriptor.qualifiedName() ).stream();
         }
     }
 
@@ -741,7 +731,7 @@ public class ModuleUnitOfWork
     }
 
     private class ToEntityManyAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
+        implements Function<AssociationDescriptor, Stream<EntityReference>>
     {
 
         private final T value;
@@ -752,17 +742,15 @@ public class ModuleUnitOfWork
         }
 
         @Override
-        public Iterable<EntityReference> apply( AssociationDescriptor associationDescriptor )
+        public Stream<EntityReference> apply( AssociationDescriptor associationDescriptor )
         {
-            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
-            ManyAssociationInstance<T> association =
-                (ManyAssociationInstance<T>) state.manyAssociationFor( associationDescriptor.accessor() );
-            return association.getManyAssociationState();
+            ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value );
+            return valueInstance.state().manyAssociationFor( associationDescriptor.accessor() ).references();
         }
     }
 
     private class ToEntityNameAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
+        implements Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>>
     {
         private final T value;
 
@@ -772,17 +760,10 @@ public class ModuleUnitOfWork
         }
 
         @Override
-        public Map<String, EntityReference> apply( AssociationDescriptor associationDescriptor )
+        public Stream<Map.Entry<String, EntityReference>> apply( 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;
+            ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value );
+            return valueInstance.state().namedAssociationFor( associationDescriptor.accessor() ).references();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java
index 7891986..b72706b 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java
@@ -19,12 +19,11 @@
  */
 package org.apache.zest.runtime.value;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Function;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.AssociationDescriptor;
 import org.apache.zest.api.association.AssociationStateHolder;
-import org.apache.zest.api.association.NamedAssociation;
 import org.apache.zest.api.common.ConstructionException;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.property.PropertyDescriptor;
@@ -54,8 +53,6 @@ public class ValueBuilderWithPrototype<T>
     )
     {
         valueModel = (ValueModel) compositeModelModule;
-        // Only shallow clone, as all generic types of the ValueComposites are expected to be Immutable.
-
         MixinsModel mixinsModel = valueModel.mixinsModel();
         Object[] mixins = mixinsModel.newMixinHolder();
         final ValueStateInstance prototypeState = ValueInstance.valueInstanceOf( (ValueComposite) prototype ).state();
@@ -79,21 +76,6 @@ public class ValueBuilderWithPrototype<T>
             mixins[ i++ ] = mixinModel.newInstance( injectionContext );
         }
 
-//        // Use serialization-deserialization to make a copy of the prototype
-//        final Object value;
-//        try
-//        {
-//            // @TODO there is probably a more efficient way to do this
-//            ValueSerialization valueSerialization = currentModule.valueSerialization();
-//            String serialized = valueSerialization.serialize( prototype );
-//            value = valueSerialization.deserialize( valueModel.valueType(), serialized);
-//        }
-//        catch( ValueSerializationException e )
-//        {
-//            throw new IllegalStateException( "Could not serialize-copy Value", e );
-//        }
-
-//        ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value );
         valueInstance.prepareToBuild();
         this.prototypeInstance = valueInstance;
     }
@@ -185,7 +167,7 @@ public class ValueBuilderWithPrototype<T>
     }
 
     private static class AssociationDescriptorIterableFunction
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
+        implements Function<AssociationDescriptor, Stream<EntityReference>>
     {
         private final ValueStateInstance prototypeState;
 
@@ -195,14 +177,14 @@ public class ValueBuilderWithPrototype<T>
         }
 
         @Override
-        public Iterable<EntityReference> apply( AssociationDescriptor descriptor )
+        public Stream<EntityReference> apply( AssociationDescriptor descriptor )
         {
             return prototypeState.manyAssociationFor( descriptor.accessor() ).references();
         }
     }
 
     private static class AssociationDescriptorMapFunction
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
+        implements Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>>
     {
         private final ValueStateInstance prototypeState;
 
@@ -212,15 +194,9 @@ public class ValueBuilderWithPrototype<T>
         }
 
         @Override
-        public Map<String, EntityReference> apply( AssociationDescriptor descriptor )
+        public Stream<Map.Entry<String, EntityReference>> apply( AssociationDescriptor descriptor )
         {
-            Map<String, EntityReference> result = new HashMap<>();
-            NamedAssociation<?> namedAssociation = prototypeState.namedAssociationFor( descriptor.accessor() );
-            for( String name : namedAssociation )
-            {
-                result.put( name, namedAssociation.referenceOf( name ) );
-            }
-            return result;
+            return prototypeState.namedAssociationFor( descriptor.accessor() ).references();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java
index d6bca20..f12f57c 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java
@@ -37,6 +37,9 @@ import org.apache.zest.runtime.property.PropertyInstance;
 import org.apache.zest.runtime.structure.ModuleInstance;
 import org.apache.zest.runtime.unitofwork.EntityFunction;
 
+import static java.util.stream.Collectors.toList;
+import static org.apache.zest.api.util.Collectors.toMap;
+
 /**
  * TODO
  */
@@ -89,9 +92,9 @@ public final class ValueStateInstance
 
         this.manyAssociations = new LinkedHashMap<>();
         valueModel.state().manyAssociations().forEach( associationDescriptor -> {
-            AssociationInfo builderInfo = associationDescriptor
-                .getBuilderInfo();
-            List<EntityReference> value = stateResolver.getManyAssociationState( associationDescriptor );
+            AssociationInfo builderInfo = associationDescriptor.getBuilderInfo();
+            List<EntityReference> value = stateResolver.getManyAssociationState( associationDescriptor )
+                                                       .collect( toList() );
             ManyAssociationValueState manyAssociationState = new ManyAssociationValueState( value );
             ManyAssociationInstance<Object> associationInstance = new ManyAssociationInstance<>(
                 builderInfo,
@@ -102,9 +105,9 @@ public final class ValueStateInstance
 
         this.namedAssociations = new LinkedHashMap<>();
         valueModel.state().namedAssociations().forEach( associationDescriptor -> {
-            AssociationInfo builderInfo = associationDescriptor
-                .getBuilderInfo();
-            Map<String, EntityReference> value = stateResolver.getNamedAssociationState( associationDescriptor );
+            AssociationInfo builderInfo = associationDescriptor.getBuilderInfo();
+            Map<String, EntityReference> value = stateResolver.getNamedAssociationState( associationDescriptor )
+                                                              .collect( toMap( LinkedHashMap::new ) );
             NamedAssociationValueState namedAssociationState = new NamedAssociationValueState( value );
             NamedAssociationInstance<Object> associationInstance = new NamedAssociationInstance<>(
                 builderInfo,

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/test/java/org/apache/zest/runtime/entity/EntityBuilderWithStateTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/zest/runtime/entity/EntityBuilderWithStateTest.java b/core/runtime/src/test/java/org/apache/zest/runtime/entity/EntityBuilderWithStateTest.java
index fddcf53..6858062 100644
--- a/core/runtime/src/test/java/org/apache/zest/runtime/entity/EntityBuilderWithStateTest.java
+++ b/core/runtime/src/test/java/org/apache/zest/runtime/entity/EntityBuilderWithStateTest.java
@@ -19,11 +19,8 @@
  */
 package org.apache.zest.runtime.entity;
 
-import java.util.Arrays;
 import java.util.Collections;
-import org.apache.zest.api.identity.Identity;
-import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
-import org.junit.Test;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.Association;
 import org.apache.zest.api.association.ManyAssociation;
 import org.apache.zest.api.association.NamedAssociation;
@@ -31,13 +28,16 @@ import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.entity.EntityBuilder;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.identity.HasIdentity;
+import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.property.Property;
 import org.apache.zest.api.unitofwork.UnitOfWork;
 import org.apache.zest.api.unitofwork.UnitOfWorkCompletionException;
 import org.apache.zest.bootstrap.AssemblyException;
 import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler;
 import org.apache.zest.test.AbstractZestTest;
 import org.apache.zest.test.EntityTestAssembler;
+import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -91,7 +91,7 @@ public class EntityBuilderWithStateTest
                 descriptor -> {
                     if( "manyAss".equals( descriptor.qualifiedName().name() ) )
                     {
-                        return Arrays.asList( EntityReference.create( associatedIdentity ) );
+                        return Stream.of( EntityReference.create( associatedIdentity ) );
                     }
                     return null;
                 },
@@ -101,7 +101,7 @@ public class EntityBuilderWithStateTest
                         return Collections.singletonMap(
                             "foo",
                             EntityReference.create( associatedIdentity )
-                        );
+                        ).entrySet().stream();
                     }
                     return null;
                 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/runtime/src/test/java/org/apache/zest/runtime/value/ValueWithAssociationTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/zest/runtime/value/ValueWithAssociationTest.java b/core/runtime/src/test/java/org/apache/zest/runtime/value/ValueWithAssociationTest.java
index 00de555..13ac968 100644
--- a/core/runtime/src/test/java/org/apache/zest/runtime/value/ValueWithAssociationTest.java
+++ b/core/runtime/src/test/java/org/apache/zest/runtime/value/ValueWithAssociationTest.java
@@ -95,10 +95,10 @@ public class ValueWithAssociationTest extends AbstractZestTest
             NamedAssociation<?> namedSimples = holder.allNamedAssociations().iterator().next();
 
             assertThat( spi.entityReferenceOf( simple ), equalTo( EntityReference.create( identity1 ) ) );
-            assertThat( spi.entityReferenceOf( simples )
+            assertThat( spi.entityReferencesOf( simples )
                             .iterator()
                             .next(), equalTo( EntityReference.create( identity1 ) ) );
-            assertThat( spi.entityReferenceOf( namedSimples )
+            assertThat( spi.entityReferencesOf( namedSimples )
                             .iterator()
                             .next()
                             .getValue(), equalTo( EntityReference.create( identity1 ) ) );

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/spi/src/main/java/org/apache/zest/spi/ZestSPI.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/zest/spi/ZestSPI.java b/core/spi/src/main/java/org/apache/zest/spi/ZestSPI.java
index 668565e..4a95c2d 100644
--- a/core/spi/src/main/java/org/apache/zest/spi/ZestSPI.java
+++ b/core/spi/src/main/java/org/apache/zest/spi/ZestSPI.java
@@ -21,6 +21,7 @@
 package org.apache.zest.spi;
 
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.zest.api.ZestAPI;
 import org.apache.zest.api.association.Association;
 import org.apache.zest.api.association.AssociationStateHolder;
@@ -54,22 +55,21 @@ public interface ZestSPI
      * @param assoc The Association for which we want to obtain the EntityReference
      * @return The EntityReference of the given Association.
      */
-    EntityReference entityReferenceOf( Association assoc );
+    EntityReference entityReferenceOf( Association<?> assoc );
 
     /**
      * Fetches the EntityReferences without loading the referenced entities.
      *
      * @param assoc The ManyAssociation for which we want to obtain the EntityReferences.
-     * @return An Iteranble of all the EntityReferences of the given ManyAssociation.
+     * @return A stream of all the EntityReferences of the given ManyAssociation.
      */
-    Iterable<EntityReference> entityReferenceOf( ManyAssociation assoc );
+    Stream<EntityReference> entityReferencesOf( ManyAssociation<?> assoc );
 
     /**
      * Fetches the EntityReferences without loading the referenced entities.
      *
      * @param assoc The NamedAssociation for which we want to obtain the EntityReference
-     * @return An Iteranble of Map.Entry with the name and EntityReference of the given NamedAssociation.
+     * @return A stream of Map.Entry with the names and EntityReferences of the given NamedAssociation.
      */
-    Iterable<Map.Entry<String,EntityReference>> entityReferenceOf( NamedAssociation assoc );
-
+    Stream<Map.Entry<String, EntityReference>> entityReferencesOf( NamedAssociation<?> assoc );
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/spi/src/main/java/org/apache/zest/spi/entity/ManyAssociationState.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/zest/spi/entity/ManyAssociationState.java b/core/spi/src/main/java/org/apache/zest/spi/entity/ManyAssociationState.java
index cf0bd01..5fd5232 100644
--- a/core/spi/src/main/java/org/apache/zest/spi/entity/ManyAssociationState.java
+++ b/core/spi/src/main/java/org/apache/zest/spi/entity/ManyAssociationState.java
@@ -20,6 +20,8 @@
 
 package org.apache.zest.spi.entity;
 
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
@@ -38,4 +40,8 @@ public interface ManyAssociationState
     boolean remove( EntityReference entityReference );
 
     EntityReference get( int index );
+
+    default Stream<EntityReference> stream() {
+        return StreamSupport.stream( spliterator(), false );
+    }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/spi/src/main/java/org/apache/zest/spi/entity/NamedAssociationState.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/zest/spi/entity/NamedAssociationState.java b/core/spi/src/main/java/org/apache/zest/spi/entity/NamedAssociationState.java
index f96f536..a9c0d94 100644
--- a/core/spi/src/main/java/org/apache/zest/spi/entity/NamedAssociationState.java
+++ b/core/spi/src/main/java/org/apache/zest/spi/entity/NamedAssociationState.java
@@ -19,6 +19,10 @@
  */
 package org.apache.zest.spi.entity;
 
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import org.apache.zest.api.entity.EntityReference;
 
 /**
@@ -41,4 +45,10 @@ public interface NamedAssociationState
     EntityReference get( String name );
 
     String nameOf( EntityReference entityReference );
+
+    default Stream<Map.Entry<String, EntityReference>> stream()
+    {
+        return StreamSupport.stream( spliterator(), false )
+                            .map( name -> new AbstractMap.SimpleImmutableEntry<>( name, get( name ) ) );
+    }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java b/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
index 85884ae..e9b8019 100644
--- a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
+++ b/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
@@ -43,6 +43,8 @@ import java.util.Map;
 import java.util.Scanner;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.identity.Identity;
 import org.apache.zest.api.identity.StringIdentity;
@@ -671,19 +673,19 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType>
                 Object entityRefs = stateMap.get( manyAssociation.qualifiedName().name() );
                 if( entityRefs == null )
                 {
-                    return Collections.emptySet();
+                    return Stream.empty();
                 }
                 //noinspection unchecked
-                return (Iterable<EntityReference>) entityRefs;
+                return StreamSupport.stream( ( (Iterable<EntityReference>) entityRefs ).spliterator(), false );
             },
             namedAssociation -> {
                 Object entityRefs = stateMap.get( namedAssociation.qualifiedName().name() );
                 if( entityRefs == null )
                 {
-                    return Collections.emptyMap();
+                    return Stream.empty();
                 }
                 //noinspection unchecked
-                return (Map<String, EntityReference>) entityRefs;
+                return ( (Map<String, EntityReference>) entityRefs ).entrySet().stream();
             } );
     }
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java b/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java
index 60093fc..cda5e67 100644
--- a/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java
+++ b/core/spi/src/main/java/org/apache/zest/spi/value/ValueSerializerAdapter.java
@@ -34,6 +34,7 @@ import java.time.Period;
 import java.time.ZonedDateTime;
 import java.util.Base64;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.function.BiFunction;
 import java.util.function.Function;
@@ -416,10 +417,10 @@ public abstract class ValueSerializerAdapter<OutputType>
                 onFieldStart( output, associationDescriptor.qualifiedName().name() );
                 onValueStart( output );
                 onArrayStart( output );
-                for( EntityReference ref : manyAssociation.references() )
+                for( Iterator<EntityReference> it = manyAssociation.references().iterator(); it.hasNext(); )
                 {
                     onValueStart( output );
-                    onValue( output, ref.identity().toString() );
+                    onValue( output, it.next().identity().toString() );
                     onValueEnd( output );
                 }
                 onArrayEnd( output );

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/restlet/requestreader/DefaultRequestReader.java
----------------------------------------------------------------------
diff --git a/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/restlet/requestreader/DefaultRequestReader.java b/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/restlet/requestreader/DefaultRequestReader.java
index b96cc29..9d6cec3 100644
--- a/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/restlet/requestreader/DefaultRequestReader.java
+++ b/libraries/rest-server/src/main/java/org/apache/zest/library/rest/server/restlet/requestreader/DefaultRequestReader.java
@@ -28,7 +28,6 @@ import java.time.LocalDateTime;
 import java.time.OffsetDateTime;
 import java.time.Period;
 import java.time.ZonedDateTime;
-import java.util.Collections;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Stream;
@@ -332,18 +331,14 @@ public class DefaultRequestReader
                     return null;
                 }
             },
-            (Function<AssociationDescriptor, Iterable<EntityReference>>) associationDescriptor -> {
+            (Function<AssociationDescriptor, Stream<EntityReference>>) associationDescriptor -> {
                 // TODO
-                return Collections.emptySet();
+                return Stream.empty();
             },
-            new Function<AssociationDescriptor, Map<String, EntityReference>>()
+            (Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>>) associationDescriptor ->
             {
-                @Override
-                public Map<String, EntityReference> apply( AssociationDescriptor from )
-                {
-                    // TODO
-                    return Collections.emptyMap();
-                }
+                // TODO
+                return Stream.empty();
             }
         );
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundManyAssociation.java
----------------------------------------------------------------------
diff --git a/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundManyAssociation.java b/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundManyAssociation.java
index 0f5870d..6b2e437 100644
--- a/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundManyAssociation.java
+++ b/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundManyAssociation.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.ManyAssociation;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.injection.scope.Service;
@@ -79,7 +80,7 @@ public class BoundManyAssociation<T> extends AbstractBinding<T>
     }
 
     @Override
-    public Iterable<EntityReference> references()
+    public Stream<EntityReference> references()
     {
         return actualAssociations.references();
     }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/8854b130/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundNamedAssociation.java
----------------------------------------------------------------------
diff --git a/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundNamedAssociation.java b/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundNamedAssociation.java
index ecfbf3b..6fc953a 100644
--- a/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundNamedAssociation.java
+++ b/samples/swing/src/main/java/org/apache/zest/sample/swing/binding/internal/BoundNamedAssociation.java
@@ -22,6 +22,7 @@ package org.apache.zest.sample.swing.binding.internal;
 import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.stream.Stream;
 import org.apache.zest.api.association.NamedAssociation;
 import org.apache.zest.api.entity.EntityReference;
 import org.apache.zest.api.injection.scope.Service;
@@ -95,7 +96,7 @@ public class BoundNamedAssociation<T>
     }
 
     @Override
-    public Iterable<EntityReference> references()
+    public Stream<Map.Entry<String, EntityReference>> references()
     {
         return actualAssociations.references();
     }