http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
index 1835dce..02b88a9 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
@@ -35,7 +35,9 @@ import javax.json.JsonValue;
 import org.apache.polygene.api.PolygeneAPI;
 import org.apache.polygene.api.association.AssociationStateHolder;
 import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.composite.Composite;
 import org.apache.polygene.api.composite.CompositeInstance;
+import 
org.apache.polygene.api.composite.StatefulAssociationCompositeDescriptor;
 import org.apache.polygene.api.injection.scope.Structure;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
@@ -43,15 +45,13 @@ import org.apache.polygene.api.mixin.Initializable;
 import org.apache.polygene.api.serialization.ConvertedBy;
 import org.apache.polygene.api.serialization.Converter;
 import org.apache.polygene.api.serialization.Converters;
+import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.structure.Module;
 import org.apache.polygene.api.type.ArrayType;
 import org.apache.polygene.api.type.MapType;
-import org.apache.polygene.api.type.ValueCompositeType;
+import org.apache.polygene.api.type.StatefulAssociationValueType;
 import org.apache.polygene.api.type.ValueType;
-import org.apache.polygene.api.util.Annotations;
-import org.apache.polygene.api.value.ValueComposite;
-import org.apache.polygene.api.value.ValueDescriptor;
 import org.apache.polygene.spi.serialization.AbstractTextSerializer;
 import org.apache.polygene.spi.serialization.JsonSerializer;
 import org.apache.polygene.spi.util.ArrayIterable;
@@ -127,11 +127,6 @@ public class JavaxJsonSerializer extends 
AbstractTextSerializer
             return JsonValue.NULL;
         }
         Class<?> objectClass = object.getClass();
-        ConvertedBy convertedBy = Annotations.annotationOn( objectClass, 
ConvertedBy.class );
-        if( convertedBy != null )
-        {
-            return doSerialize( options, module.newObject( convertedBy.value() 
).toString( object ), false );
-        }
         Converter<Object> converter = converters.converterFor( objectClass );
         if( converter != null )
         {
@@ -140,12 +135,11 @@ public class JavaxJsonSerializer extends 
AbstractTextSerializer
         JavaxJsonAdapter<?> adapter = adapters.adapterFor( objectClass );
         if( adapter != null )
         {
-            return adapter.serialize( jsonFactories.builderFactory(), object,
-                                      obj -> doSerialize( options, obj, false 
) );
+            return adapter.serialize( jsonFactories, object, obj -> 
doSerialize( options, obj, false ) );
         }
-        if( ValueCompositeType.isValueComposite( objectClass ) )
+        if( StatefulAssociationValueType.isStatefulAssociationValue( 
objectClass ) )
         {
-            return serializeValueComposite( options, object, root );
+            return serializeStatefulAssociationValue( options, object, root );
         }
         if( MapType.isMap( objectClass ) )
         {
@@ -163,17 +157,16 @@ public class JavaxJsonSerializer extends 
AbstractTextSerializer
         {
             return serializeStream( options, (Stream<?>) object );
         }
-        // Fallback to Java Serialization in Base 64
-        byte[] bytes = Base64.getEncoder().encode( serializeJava( object ) );
-        return JavaxJson.toJsonString( new String( bytes, UTF_8 ) );
+        throw new SerializationException( "Don't know how to serialize " + 
object );
     }
 
-    private JsonObject serializeValueComposite( Options options, Object 
composite, boolean root )
+    private JsonObject serializeStatefulAssociationValue( Options options, 
Object composite, boolean root )
     {
-        CompositeInstance instance = 
PolygeneAPI.FUNCTION_COMPOSITE_INSTANCE_OF.apply( (ValueComposite) composite );
-        ValueDescriptor descriptor = (ValueDescriptor) instance.descriptor();
+        CompositeInstance instance = 
PolygeneAPI.FUNCTION_COMPOSITE_INSTANCE_OF.apply( (Composite) composite );
+        StatefulAssociationCompositeDescriptor descriptor =
+            (StatefulAssociationCompositeDescriptor) instance.descriptor();
         AssociationStateHolder state = (AssociationStateHolder) 
instance.state();
-        ValueCompositeType valueType = descriptor.valueType();
+        StatefulAssociationValueType<?> valueType = descriptor.valueType();
 
         JsonObjectBuilder builder = 
jsonFactories.builderFactory().createObjectBuilder();
         valueType.properties().forEach(
@@ -204,16 +197,16 @@ public class JavaxJsonSerializer extends 
AbstractTextSerializer
                              state.namedAssociationFor( association.accessor() 
).references()
                                   .collect( toMap() ),
                              false ) ) );
-        if( !root && options.includeTypeInfo() )
+        if( ( root && options.rootTypeInfo() ) || ( !root && 
options.nestedTypeInfo() ) )
         {
             withTypeInfo( builder, valueType );
         }
         return builder.build();
     }
 
-    private JsonObjectBuilder withTypeInfo( JsonObjectBuilder builder, 
ValueType valueType )
+    private void withTypeInfo( JsonObjectBuilder builder, ValueType valueType )
     {
-        return builder.add( settings.getTypeInfoPropertyName(), 
valueType.primaryType().getName() );
+        builder.add( settings.getTypeInfoPropertyName(), 
valueType.primaryType().getName() );
     }
 
     /**
@@ -258,7 +251,7 @@ public class JavaxJsonSerializer extends 
AbstractTextSerializer
         if( valueType.isArrayOfPrimitiveBytes() )
         {
             byte[] base64 = Base64.getEncoder().encode( (byte[]) object );
-            return JavaxJson.toJsonString( new String( base64, UTF_8 ) );
+            return jsonFactories.toJsonString( new String( base64, UTF_8 ) );
         }
         if( valueType.isArrayOfPrimitives() )
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONEntityState.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONEntityState.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONEntityState.java
index 151f144..0c38436 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONEntityState.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONEntityState.java
@@ -18,22 +18,20 @@
 package org.apache.polygene.spi.entitystore.helpers;
 
 import java.time.Instant;
-import java.util.Map;
-import javax.json.Json;
+import java.util.Objects;
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
 import javax.json.JsonValue;
 import org.apache.polygene.api.common.QualifiedName;
 import org.apache.polygene.api.entity.EntityDescriptor;
 import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.property.PropertyDescriptor;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.ValueType;
-import org.apache.polygene.api.value.ValueDescriptor;
-import org.apache.polygene.serialization.javaxjson.JavaxJson;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entity.EntityState;
 import org.apache.polygene.spi.entity.EntityStatus;
 import org.apache.polygene.spi.entity.ManyAssociationState;
@@ -41,26 +39,20 @@ import org.apache.polygene.spi.entity.NamedAssociationState;
 import org.apache.polygene.spi.entitystore.EntityStoreException;
 import org.apache.polygene.spi.serialization.JsonSerialization;
 
+import static 
org.apache.polygene.api.serialization.Serializer.Options.ALL_TYPE_INFO;
+
 /**
  * Standard JSON implementation of EntityState.
  */
 public final class JSONEntityState
     implements EntityState
 {
-    private static final String[] CLONE_NAMES =
-        {
-            JSONKeys.IDENTITY,
-            JSONKeys.APPLICATION_VERSION,
-            JSONKeys.TYPE,
-            JSONKeys.VERSION,
-            JSONKeys.MODIFIED
-        };
-
     private final ModuleDescriptor module;
     private final String version;
     private final EntityReference reference;
     private final EntityDescriptor entityDescriptor;
     private final JsonSerialization serialization;
+    private final JavaxJsonFactories jsonFactories;
 
     private EntityStatus status;
     private Instant lastModified;
@@ -68,6 +60,7 @@ public final class JSONEntityState
 
     /* package */ JSONEntityState( ModuleDescriptor module,
                                    JsonSerialization serialization,
+                                   JavaxJsonFactories jsonFactories,
                                    String version,
                                    Instant lastModified,
                                    EntityReference reference,
@@ -78,6 +71,7 @@ public final class JSONEntityState
     {
         this.module = module;
         this.serialization = serialization;
+        this.jsonFactories = jsonFactories;
         this.version = version;
         this.lastModified = lastModified;
         this.reference = reference;
@@ -110,45 +104,9 @@ public final class JSONEntityState
     {
         try
         {
-            JsonValue json = state.getJsonObject( JSONKeys.PROPERTIES ).get( 
stateName.name() );
-            if( json == null || JsonValue.NULL.equals( json ) )
-            {
-                return null;
-            }
-            else
-            {
-                // TODO This rely on _type explicitely :(
-                // Needed because of this mess that is JsonEntityState
-                ValueType propertyValueType = null;
-                ModuleDescriptor propertyModule = module;
-                if( json.getValueType() == JsonValue.ValueType.OBJECT )
-                {
-                    String typeInfo = ( (JsonObject) json ).getString( 
"_type", null );
-                    if( typeInfo != null )
-                    {
-                        ValueDescriptor valueDescriptor = 
module.valueDescriptor( typeInfo );
-                        if( valueDescriptor != null )
-                        {
-                            propertyValueType = valueDescriptor.valueType();
-                            propertyModule = valueDescriptor.module();
-                        }
-                    }
-                }
-                if( propertyValueType == null )
-                {
-                    PropertyDescriptor descriptor = entityDescriptor.state()
-                                                                    
.findPropertyModelByQualifiedName( stateName );
-                    if( descriptor != null )
-                    {
-                        propertyValueType = descriptor.valueType();
-                    }
-                }
-                if( propertyValueType == null )
-                {
-                    return null;
-                }
-                return serialization.fromJson( propertyModule, 
propertyValueType, json );
-            }
+            ValueType valueType = 
entityDescriptor.state().findPropertyModelByQualifiedName( stateName 
).valueType();
+            JsonValue jsonValue = state.getJsonObject( JSONKeys.VALUE ).get( 
stateName.name() );
+            return serialization.fromJson( module, valueType, jsonValue );
         }
         catch( SerializationException e )
         {
@@ -161,9 +119,11 @@ public final class JSONEntityState
     {
         try
         {
-            JsonValue jsonValue = serialization.toJson( newValue );
-            stateCloneWithProperty( stateName.name(), jsonValue );
-            markUpdated();
+            JsonValue jsonValue = serialization.toJson( ALL_TYPE_INFO, 
newValue );
+            if( stateCloneWithProperty( stateName.name(), jsonValue ) )
+            {
+                markUpdated();
+            }
         }
         catch( SerializationException e )
         {
@@ -174,31 +134,33 @@ public final class JSONEntityState
     @Override
     public EntityReference associationValueOf( QualifiedName stateName )
     {
-        String jsonValue = state.getJsonObject( JSONKeys.ASSOCIATIONS 
).getString( stateName.name(), null );
-        if( jsonValue == null )
+        JsonValue associationValue = state.getJsonObject( JSONKeys.VALUE 
).get( stateName.name() );
+        if( associationValue == JsonValue.NULL )
         {
             return null;
         }
-        return EntityReference.parseEntityReference( jsonValue );
+        return EntityReference.parseEntityReference( ( (JsonString) 
associationValue ).getString() );
     }
 
     @Override
-    public void setAssociationValue( QualifiedName stateName, EntityReference 
newEntity )
+    public void setAssociationValue( QualifiedName stateName, EntityReference 
entityReference )
     {
-        stateCloneWithAssociation( stateName.name(), newEntity );
-        markUpdated();
+        if( stateCloneWithAssociation( stateName.name(), entityReference ) )
+        {
+            markUpdated();
+        }
     }
 
     @Override
     public ManyAssociationState manyAssociationValueOf( QualifiedName 
stateName )
     {
-        return new JSONManyAssociationState( this, stateName.name() );
+        return new JSONManyAssociationState( jsonFactories, this, 
stateName.name() );
     }
 
     @Override
     public NamedAssociationState namedAssociationValueOf( QualifiedName 
stateName )
     {
-        return new JSONNamedAssociationState( this, stateName.name() );
+        return new JSONNamedAssociationState( jsonFactories, this, 
stateName.name() );
     }
 
     @Override
@@ -233,7 +195,7 @@ public final class JSONEntityState
     @Override
     public String toString()
     {
-        return reference + "(" + state + ")";
+        return state.toString();
     }
 
     void markUpdated()
@@ -246,215 +208,133 @@ public final class JSONEntityState
 
     void stateCloneWithVersionAndModified( String version, Instant 
lastModified )
     {
-        JsonObjectBuilder builder = JavaxJson.toBuilder( state );
-        builder.add( JSONKeys.VERSION, version );
-        builder.add( JSONKeys.MODIFIED, lastModified.toEpochMilli() );
-        state = builder.build();
+        state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VERSION, 
JSONKeys.MODIFIED )
+                             .add( JSONKeys.VERSION, version )
+                             .add( JSONKeys.MODIFIED, 
lastModified.toEpochMilli() )
+                             .build();
     }
 
-    void stateCloneWithProperty( String stateName, JsonValue value )
+    private boolean stateCloneWithProperty( String stateName, JsonValue value )
     {
-        JsonObjectBuilder builder = stateShallowClone();
-        JsonObjectBuilder propertiesBuilder = JavaxJson.toBuilder( 
state.getJsonObject( JSONKeys.PROPERTIES ) );
+        JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
+        if( Objects.equals( valueState.get( stateName ), value ) )
+        {
+            return false;
+        }
+        JsonObjectBuilder valueBuilder = jsonFactories.cloneBuilderExclude( 
valueState, stateName );
         if( value == null )
         {
-            propertiesBuilder.add( stateName, JsonValue.NULL );
+            valueBuilder.addNull( stateName );
         }
         else
         {
-            propertiesBuilder.add( stateName, value );
+            valueBuilder.add( stateName, value );
         }
-        builder.add( JSONKeys.PROPERTIES, propertiesBuilder.build() );
-        builder.add( JSONKeys.ASSOCIATIONS, state.get( JSONKeys.ASSOCIATIONS ) 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, state.get( 
JSONKeys.MANY_ASSOCIATIONS ) );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, state.get( 
JSONKeys.NAMED_ASSOCIATIONS ) );
-        state = builder.build();
+        state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VALUE )
+                             .add( JSONKeys.VALUE, valueBuilder.build() )
+                             .build();
+        return true;
     }
 
-    void stateCloneWithAssociation( String stateName, EntityReference ref )
+    private boolean stateCloneWithAssociation( String stateName, 
EntityReference ref )
     {
-        JsonObjectBuilder builder = stateShallowClone();
-        JsonObjectBuilder assocBuilder = JavaxJson.toBuilder( 
state.getJsonObject( JSONKeys.ASSOCIATIONS ) );
-        if( ref == null )
+        JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
+        JsonValue jsonRef = ref == null ? JsonValue.NULL : 
jsonFactories.toJsonString( ref.identity().toString() );
+        if( Objects.equals( valueState.get( stateName ), jsonRef ) )
         {
-            assocBuilder.add( stateName, JsonValue.NULL );
+            return false;
         }
-        else
-        {
-            assocBuilder.add( stateName, ref.identity().toString() );
-        }
-        builder.add( JSONKeys.PROPERTIES, state.get( JSONKeys.PROPERTIES ) );
-        builder.add( JSONKeys.ASSOCIATIONS, assocBuilder.build() );
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, state.get( 
JSONKeys.MANY_ASSOCIATIONS ) );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, state.get( 
JSONKeys.NAMED_ASSOCIATIONS ) );
-        state = builder.build();
+        valueState = jsonFactories.cloneBuilderExclude( valueState, stateName )
+                                  .add( stateName, jsonRef )
+                                  .build();
+        state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VALUE )
+                             .add( JSONKeys.VALUE, valueState )
+                             .build();
+        return true;
     }
 
     void stateCloneAddManyAssociation( int idx, String stateName, 
EntityReference ref )
     {
-        JsonObjectBuilder builder = stateShallowClone();
-        JsonObjectBuilder manyAssociations = Json.createObjectBuilder();
-        JsonObject previousManyAssociations = state.getJsonObject( 
JSONKeys.MANY_ASSOCIATIONS );
-        for( Map.Entry<String, JsonValue> previousManyAssociation : 
previousManyAssociations.entrySet() )
+        JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
+        String identity = ref.identity().toString();
+        JsonArray manyAssoc;
+        if( valueState.containsKey( stateName ) )
         {
-            String key = previousManyAssociation.getKey();
-            if( !key.equals( stateName ) )
+            JsonArrayBuilder manyAssocBuilder = 
jsonFactories.builderFactory().createArrayBuilder();
+            JsonArray previousManyAssoc = valueState.getJsonArray( stateName );
+            int currentIdx = 0;
+            for( JsonValue jsonRef : previousManyAssoc )
             {
-                manyAssociations.add( key, previousManyAssociation.getValue() 
);
-            }
-        }
-        JsonValue previousReferences = previousManyAssociations.get( stateName 
);
-        JsonArrayBuilder references = Json.createArrayBuilder();
-        String newRef = ref.identity().toString();
-        if( previousReferences == null || previousReferences.getValueType() != 
JsonValue.ValueType.ARRAY )
-        {
-            references.add( newRef );
-        }
-        else
-        {
-            JsonArray previousReferencesArray = (JsonArray) previousReferences;
-            boolean insert = !previousReferencesArray.contains( newRef );
-            for( int i = 0; i < previousReferencesArray.size(); i++ )
-            {
-                if( insert && i == idx )
+                if( currentIdx == idx )
                 {
-                    references.add( newRef );
+                    manyAssocBuilder.add( identity );
                 }
-                references.add( previousReferencesArray.getString( i ) );
+                manyAssocBuilder.add( jsonRef );
+                currentIdx++;
             }
-            if( insert && idx >= previousReferencesArray.size() )
+            if( idx >= previousManyAssoc.size() )
             {
-                references.add( newRef );
+                manyAssocBuilder.add( identity );
             }
+            manyAssoc = manyAssocBuilder.build();
+        }
+        else
+        {
+            manyAssoc = 
jsonFactories.builderFactory().createArrayBuilder().add( identity ).build();
         }
-        manyAssociations.add( stateName, references.build() );
-        builder.add( JSONKeys.PROPERTIES, state.get( JSONKeys.PROPERTIES ) );
-        builder.add( JSONKeys.ASSOCIATIONS, state.get( JSONKeys.ASSOCIATIONS ) 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, manyAssociations.build() );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, state.get( 
JSONKeys.NAMED_ASSOCIATIONS ) );
-        state = builder.build();
+        valueState = jsonFactories.cloneBuilderExclude( valueState, stateName )
+                                  .add( stateName, manyAssoc )
+                                  .build();
+        state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VALUE )
+                             .add( JSONKeys.VALUE, valueState )
+                             .build();
     }
 
     void stateCloneRemoveManyAssociation( String stateName, EntityReference 
ref )
     {
-        String stringRef = ref.identity().toString();
-        JsonObjectBuilder builder = stateShallowClone();
-        JsonObjectBuilder manyAssociations = Json.createObjectBuilder();
-        JsonObject previousManyAssociations = state.getJsonObject( 
JSONKeys.MANY_ASSOCIATIONS );
-        for( Map.Entry<String, JsonValue> previousManyAssociation : 
previousManyAssociations.entrySet() )
+        JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
+        if( valueState.containsKey( stateName ) )
         {
-            String key = previousManyAssociation.getKey();
-            if( !key.equals( stateName ) )
-            {
-                manyAssociations.add( key, previousManyAssociation.getValue() 
);
-            }
+            String identity = ref.identity().toString();
+            JsonArray manyAssoc = jsonFactories.cloneBuilderExclude( 
valueState.getJsonArray( stateName ),
+                                                                     
jsonFactories.toJsonString( identity ) )
+                                               .build();
+            valueState = jsonFactories.cloneBuilderExclude( valueState, 
stateName )
+                                      .add( stateName, manyAssoc ).build();
+            state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VALUE )
+                                 .add( JSONKeys.VALUE, valueState )
+                                 .build();
         }
-        JsonValue previousReferences = previousManyAssociations.get( stateName 
);
-        JsonArrayBuilder references = Json.createArrayBuilder();
-        if( previousReferences != null && previousReferences.getValueType() == 
JsonValue.ValueType.ARRAY )
-        {
-            JsonArray previousReferencesArray = (JsonArray) previousReferences;
-            for( int idx = 0; idx < previousReferencesArray.size(); idx++ )
-            {
-                String previousRef = previousReferencesArray.getString( idx );
-                if( !stringRef.equals( previousRef ) )
-                {
-                    references.add( previousRef );
-                }
-            }
-        }
-        manyAssociations.add( stateName, references.build() );
-        builder.add( JSONKeys.PROPERTIES, state.get( JSONKeys.PROPERTIES ) );
-        builder.add( JSONKeys.ASSOCIATIONS, state.get( JSONKeys.ASSOCIATIONS ) 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, manyAssociations.build() );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, state.get( 
JSONKeys.NAMED_ASSOCIATIONS ) );
-        state = builder.build();
     }
 
     void stateCloneAddNamedAssociation( String stateName, String name, 
EntityReference ref )
     {
-        JsonObjectBuilder builder = stateShallowClone();
-        JsonObject previousNamedAssociations = state.getJsonObject( 
JSONKeys.NAMED_ASSOCIATIONS );
-        JsonObjectBuilder namedAssociations = Json.createObjectBuilder();
-        for( Map.Entry<String, JsonValue> previousNamedAssociation : 
previousNamedAssociations.entrySet() )
-        {
-            String key = previousNamedAssociation.getKey();
-            if( !key.equals( stateName ) )
-            {
-                namedAssociations.add( key, 
previousNamedAssociation.getValue() );
-            }
-        }
-        JsonValue previousReferences = previousNamedAssociations.get( 
stateName );
-        JsonObjectBuilder references = Json.createObjectBuilder();
-        String newRef = ref.identity().toString();
-        if( previousReferences == null || !( previousReferences instanceof 
JsonObject ) )
-        {
-            references.add( name, newRef );
-        }
-        else
-        {
-            JsonObject previousReferencesObject = (JsonObject) 
previousReferences;
-            for( Map.Entry<String, JsonValue> previousNamedReference : 
previousReferencesObject.entrySet() )
-            {
-                String key = previousNamedReference.getKey();
-                if( !key.equals( name ) )
-                {
-                    references.add( key, previousNamedReference.getValue() );
-                }
-            }
-            references.add( name, ref.identity().toString() );
-        }
-        namedAssociations.add( stateName, references.build() );
-        builder.add( JSONKeys.PROPERTIES, state.get( JSONKeys.PROPERTIES ) );
-        builder.add( JSONKeys.ASSOCIATIONS, state.get( JSONKeys.ASSOCIATIONS ) 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, state.get( 
JSONKeys.MANY_ASSOCIATIONS ) );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, namedAssociations.build() );
-        state = builder.build();
+        JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
+        JsonObjectBuilder namedAssoc = valueState.containsKey( stateName )
+                                       ? jsonFactories.cloneBuilder( 
valueState.getJsonObject( stateName ) )
+                                       : 
jsonFactories.builderFactory().createObjectBuilder();
+        namedAssoc.add( name, ref.identity().toString() );
+        valueState = jsonFactories.cloneBuilderExclude( valueState, stateName )
+                                  .add( stateName, namedAssoc.build() )
+                                  .build();
+        state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VALUE )
+                             .add( JSONKeys.VALUE, valueState )
+                             .build();
     }
 
     void stateCloneRemoveNamedAssociation( String stateName, String name )
     {
-        JsonObjectBuilder builder = stateShallowClone();
-        JsonObjectBuilder namedAssociations = Json.createObjectBuilder();
-        JsonObject previousNamedAssociations = state.getJsonObject( 
JSONKeys.NAMED_ASSOCIATIONS );
-        for( Map.Entry<String, JsonValue> previousNamedAssociation : 
previousNamedAssociations.entrySet() )
-        {
-            String key = previousNamedAssociation.getKey();
-            if( !key.equals( stateName ) )
-            {
-                namedAssociations.add( key, 
previousNamedAssociation.getValue() );
-            }
-        }
-        JsonValue previousReferences = previousNamedAssociations.get( 
stateName );
-        JsonObjectBuilder references = Json.createObjectBuilder();
-        if( previousReferences != null && previousReferences.getValueType() == 
JsonValue.ValueType.OBJECT )
-        {
-            JsonObject previousReferencesObject = (JsonObject) 
previousReferences;
-            for( Map.Entry<String, JsonValue> previousNamedRef : 
previousReferencesObject.entrySet() )
-            {
-                String previousName = previousNamedRef.getKey();
-                if( !name.equals( previousName ) )
-                {
-                    references.add( previousName, previousNamedRef.getValue() 
);
-                }
-            }
-        }
-        namedAssociations.add( stateName, references.build() );
-        builder.add( JSONKeys.PROPERTIES, state.get( JSONKeys.PROPERTIES ) );
-        builder.add( JSONKeys.ASSOCIATIONS, state.get( JSONKeys.ASSOCIATIONS ) 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, state.get( 
JSONKeys.MANY_ASSOCIATIONS ) );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, namedAssociations.build() );
-        state = builder.build();
-    }
-
-    private JsonObjectBuilder stateShallowClone()
-    {
-        JsonObjectBuilder builder = Json.createObjectBuilder();
-        for( String cloneName : CLONE_NAMES )
+        JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
+        if( valueState.containsKey( stateName ) )
         {
-            JsonValue cloneValue = state.get( cloneName );
-            builder.add( cloneName, cloneValue == null ? JsonValue.NULL : 
cloneValue );
+            JsonObject namedAssoc = jsonFactories.cloneBuilderExclude( 
valueState.getJsonObject( stateName ), name )
+                                                 .build();
+            valueState = jsonFactories.cloneBuilderExclude( valueState, 
stateName )
+                                      .add( stateName, namedAssoc )
+                                      .build();
+            state = jsonFactories.cloneBuilderExclude( state, JSONKeys.VALUE )
+                                 .add( JSONKeys.VALUE, valueState )
+                                 .build();
         }
-        return builder;
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONKeys.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONKeys.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONKeys.java
index 6e9984c..4c0fa0e 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONKeys.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONKeys.java
@@ -47,19 +47,7 @@ public interface JSONKeys
      */
     String MODIFIED = "modified";
     /**
-     * Map of properties.
+     * Entity value state.
      */
-    String PROPERTIES = "properties";
-    /**
-     * Map of associations.
-     */
-    String ASSOCIATIONS = "associations";
-    /**
-     * Map of manyassociations.
-     */
-    String MANY_ASSOCIATIONS = "manyassociations";
-    /**
-     * Map of namedassociations.
-     */
-    String NAMED_ASSOCIATIONS = "namedassociations";
+    String VALUE = "value";
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationState.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationState.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationState.java
index e9b99c4..3bdd047 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationState.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationState.java
@@ -21,12 +21,11 @@ package org.apache.polygene.spi.entitystore.helpers;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
-import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonException;
-import javax.json.JsonObject;
 import javax.json.JsonValue;
 import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entity.ManyAssociationState;
 import org.apache.polygene.spi.entitystore.EntityStoreException;
 
@@ -37,24 +36,27 @@ import 
org.apache.polygene.spi.entitystore.EntityStoreException;
 public final class JSONManyAssociationState
     implements ManyAssociationState
 {
+    private final JavaxJsonFactories jsonFactories;
     private final JSONEntityState entityState;
     private final String stateName;
 
-    /* package */ JSONManyAssociationState( JSONEntityState entityState, 
String stateName )
+    /* package */ JSONManyAssociationState( JavaxJsonFactories jsonFactories,
+                                            JSONEntityState entityState,
+                                            String stateName )
     {
+        this.jsonFactories = jsonFactories;
         this.entityState = entityState;
         this.stateName = stateName;
     }
 
     private JsonArray getReferences()
     {
-        JsonObject manyAssociations = entityState.state().getJsonObject( 
JSONKeys.MANY_ASSOCIATIONS );
-        JsonValue references = manyAssociations.get( stateName );
+        JsonValue references = entityState.state().getJsonObject( 
JSONKeys.VALUE ).get( stateName );
         if( references != null && references.getValueType() == 
JsonValue.ValueType.ARRAY )
         {
             return (JsonArray) references;
         }
-        return Json.createArrayBuilder().build();
+        return jsonFactories.builderFactory().createArrayBuilder().build();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONMapEntityStoreMixin.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONMapEntityStoreMixin.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONMapEntityStoreMixin.java
index 2a0ddc3..d593eb0 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONMapEntityStoreMixin.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONMapEntityStoreMixin.java
@@ -17,6 +17,7 @@
  */
 package org.apache.polygene.spi.entitystore.helpers;
 
+import java.io.BufferedReader;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -30,7 +31,6 @@ import java.util.List;
 import java.util.UUID;
 import java.util.function.Function;
 import java.util.stream.Stream;
-import javax.json.Json;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonReader;
@@ -50,7 +50,7 @@ import org.apache.polygene.api.structure.Application;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.unitofwork.NoSuchEntityTypeException;
 import org.apache.polygene.api.usecase.Usecase;
-import org.apache.polygene.serialization.javaxjson.JavaxJson;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.cache.Cache;
 import org.apache.polygene.spi.cache.CachePool;
 import org.apache.polygene.spi.cache.NullCache;
@@ -64,6 +64,8 @@ import 
org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
 import org.apache.polygene.spi.entitystore.StateCommitter;
 import org.apache.polygene.spi.serialization.JsonSerialization;
 
+import static java.util.stream.Collectors.joining;
+
 /**
  * Implementation of EntityStore that works with an implementation of 
MapEntityStore.
  *
@@ -88,6 +90,9 @@ public class JSONMapEntityStoreMixin
     private JsonSerialization serialization;
 
     @Service
+    private JavaxJsonFactories jsonFactories;
+
+    @Service
     IdentityGenerator identityGenerator;
 
     @Optional
@@ -152,19 +157,16 @@ public class JSONMapEntityStoreMixin
     {
         try
         {
-            JsonObjectBuilder builder = Json.createObjectBuilder();
+            JsonObjectBuilder builder = 
jsonFactories.builderFactory().createObjectBuilder();
             builder.add( JSONKeys.IDENTITY, reference.identity().toString() );
             builder.add( JSONKeys.APPLICATION_VERSION, application.version() );
             builder.add( JSONKeys.TYPE, 
entityDescriptor.types().findFirst().get().getName() );
             builder.add( JSONKeys.VERSION, uow.identity().toString() );
             builder.add( JSONKeys.MODIFIED, uow.currentTime().toEpochMilli() );
-            builder.add( JSONKeys.PROPERTIES, 
Json.createObjectBuilder().build() );
-            builder.add( JSONKeys.ASSOCIATIONS, 
Json.createObjectBuilder().build() );
-            builder.add( JSONKeys.MANY_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
-            builder.add( JSONKeys.NAMED_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
+            builder.add( JSONKeys.VALUE, 
jsonFactories.builderFactory().createObjectBuilder().build() );
             JsonObject state = builder.build();
-            return new JSONEntityState( entityDescriptor.module(), 
serialization,
-                                        "", uow.currentTime(),
+            return new JSONEntityState( entityDescriptor.module(), 
serialization, jsonFactories,
+                                        uow.identity().toString(), 
uow.currentTime(),
                                         reference,
                                         EntityStatus.NEW, entityDescriptor,
                                         state );
@@ -199,7 +201,7 @@ public class JSONMapEntityStoreMixin
                 }
                 if( doCacheOnRead( uow ) )
                 {
-                    cache.put( reference.identity().toString(), new 
CacheState( loadedState.state() ) );
+                    cache.put( reference.identity().toString(), new 
CacheState( loadedState.state().toString() ) );
                 }
                 return loadedState;
             }
@@ -220,13 +222,13 @@ public class JSONMapEntityStoreMixin
         CacheState cacheState = cache.get( reference.identity().toString() );
         if( cacheState != null )
         {
-            return cacheState.json.getString( JSONKeys.VERSION );
+            return jsonFactories.readerFactory().createReader( new 
StringReader( cacheState.string ) ).readObject()
+                                .getString( JSONKeys.VERSION );
         }
-        try
+        // Get state
+        try( JsonReader reader = jsonFactories.readerFactory().createReader( 
mapEntityStore.get( reference ) ) )
         {
-            // Get state
-            Reader entityState = mapEntityStore.get( reference );
-            return Json.createReader( entityState ).readObject().getString( 
JSONKeys.VERSION );
+            return reader.readObject().getString( JSONKeys.VERSION );
         }
         catch( EntityStoreException ex )
         {
@@ -275,7 +277,7 @@ public class JSONMapEntityStoreMixin
                                     if( options.cacheOnNew() )
                                     {
                                         cache.put( 
state.entityReference().identity().toString(),
-                                                   new CacheState( 
state.state() ) );
+                                                   new CacheState( 
state.state().toString() ) );
                                     }
                                 }
                                 else if( state.status().equals( 
EntityStatus.UPDATED ) )
@@ -291,7 +293,7 @@ public class JSONMapEntityStoreMixin
                                     if( options.cacheOnWrite() )
                                     {
                                         cache.put( 
state.entityReference().identity().toString(),
-                                                   new CacheState( 
state.state() ) );
+                                                   new CacheState( 
state.state().toString() ) );
                                     }
                                 }
                                 else if( state.status().equals( 
EntityStatus.REMOVED ) )
@@ -412,10 +414,10 @@ public class JSONMapEntityStoreMixin
     protected JSONEntityState readEntityState( ModuleDescriptor module, Reader 
entityState )
         throws EntityStoreException
     {
-        try
+        try( JsonReader reader = jsonFactories.readerFactory().createReader( 
entityState ) )
         {
-            JsonObject parsedState = Json.createReader( entityState 
).readObject();
-            JsonObjectBuilder jsonStateBuilder = JavaxJson.toBuilder( 
parsedState );
+            JsonObject parsedState = reader.readObject();
+            JsonObjectBuilder jsonStateBuilder = jsonFactories.cloneBuilder( 
parsedState );
             EntityStatus status = EntityStatus.LOADED;
 
             String version = parsedState.getString( JSONKeys.VERSION );
@@ -453,7 +455,7 @@ public class JSONMapEntityStoreMixin
                 throw new NoSuchEntityTypeException( type, module.name(), 
module.typeLookup() );
             }
 
-            return new JSONEntityState( entityDescriptor.module(), 
serialization,
+            return new JSONEntityState( entityDescriptor.module(), 
serialization, jsonFactories,
                                         version, modified,
                                         EntityReference.create( identity ),
                                         status, entityDescriptor,
@@ -473,12 +475,10 @@ public class JSONMapEntityStoreMixin
     @Override
     public JsonObject jsonStateOf( String id )
     {
-        try( Reader reader = mapEntityStore.get( 
EntityReference.parseEntityReference( id ) ) )
+        try( JsonReader jsonReader = jsonFactories
+            .readerFactory().createReader( mapEntityStore.get( 
EntityReference.parseEntityReference( id ) ) ) )
         {
-            try( JsonReader jsonReader = Json.createReader( reader ) )
-            {
-                return jsonReader.readObject();
-            }
+            return jsonReader.readObject();
         }
         catch( EntityStoreException ex )
         {
@@ -495,18 +495,19 @@ public class JSONMapEntityStoreMixin
         CacheState cacheState = cache.get( reference.identity().toString() );
         if( cacheState != null )
         {
-            JsonObject data = cacheState.json;
+            JsonObject state = jsonFactories.readerFactory().createReader( new 
StringReader( cacheState.string ) )
+                                            .readObject();
             try
             {
-                String type = data.getString( JSONKeys.TYPE );
+                String type = state.getString( JSONKeys.TYPE );
                 EntityDescriptor entityDescriptor = module.entityDescriptor( 
type );
-                String version = data.getString( JSONKeys.VERSION );
-                Instant lastModified = Instant.ofEpochMilli( 
data.getJsonNumber( JSONKeys.MODIFIED ).longValueExact() );
-                return new JSONEntityState( entityDescriptor.module(), 
serialization,
-                                            version, lastModified,
+                String version = state.getString( JSONKeys.VERSION );
+                Instant modified = Instant.ofEpochMilli( state.getJsonNumber( 
JSONKeys.MODIFIED ).longValueExact() );
+                return new JSONEntityState( entityDescriptor.module(), 
serialization, jsonFactories,
+                                            version, modified,
                                             reference,
                                             EntityStatus.LOADED, 
entityDescriptor,
-                                            data );
+                                            state );
             }
             catch( Exception e )
             {
@@ -526,29 +527,32 @@ public class JSONMapEntityStoreMixin
     public static class CacheState
         implements Externalizable
     {
-        public JsonObject json;
+        public String string;
 
         public CacheState()
         {
         }
 
-        private CacheState( JsonObject state )
+        private CacheState( String string )
         {
-            json = state;
+            this.string = string;
         }
 
         @Override
         public void writeExternal( ObjectOutput out )
             throws IOException
         {
-            out.writeUTF( json.toString() );
+            out.writeUTF( string );
         }
 
         @Override
         public void readExternal( ObjectInput in )
             throws IOException, ClassNotFoundException
         {
-            json = Json.createReader( new StringReader( in.readUTF() ) 
).readObject();
+            try( BufferedReader reader = new BufferedReader( new StringReader( 
in.readUTF() ) ) )
+            {
+                string = reader.lines().collect( joining( "\n" ) );
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONNamedAssociationState.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONNamedAssociationState.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONNamedAssociationState.java
index 74ea667..a59f50d 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONNamedAssociationState.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/JSONNamedAssociationState.java
@@ -23,11 +23,11 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
-import javax.json.Json;
 import javax.json.JsonException;
 import javax.json.JsonObject;
 import javax.json.JsonValue;
 import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entity.NamedAssociationState;
 import org.apache.polygene.spi.entitystore.EntityStoreException;
 
@@ -38,25 +38,27 @@ import 
org.apache.polygene.spi.entitystore.EntityStoreException;
 public final class JSONNamedAssociationState
     implements NamedAssociationState
 {
-
+    private final JavaxJsonFactories jsonFactories;
     private final JSONEntityState entityState;
     private final String stateName;
 
-    /* package */ JSONNamedAssociationState( JSONEntityState entityState, 
String stateName )
+    /* package */ JSONNamedAssociationState( JavaxJsonFactories jsonFactories,
+                                             JSONEntityState entityState,
+                                             String stateName )
     {
+        this.jsonFactories = jsonFactories;
         this.entityState = entityState;
         this.stateName = stateName;
     }
 
     private JsonObject getReferences()
     {
-        JsonObject namedAssociations = entityState.state().getJsonObject( 
JSONKeys.NAMED_ASSOCIATIONS );
-        JsonValue references = namedAssociations.get( stateName );
+        JsonValue references = entityState.state().getJsonObject( 
JSONKeys.VALUE ).get( stateName );
         if( references != null && references.getValueType() == 
JsonValue.ValueType.OBJECT )
         {
             return (JsonObject) references;
         }
-        return Json.createObjectBuilder().build();
+        return jsonFactories.builderFactory().createObjectBuilder().build();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/MapEntityStoreMixin.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/MapEntityStoreMixin.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/MapEntityStoreMixin.java
index ef9816c..c8bd163 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/MapEntityStoreMixin.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/entitystore/helpers/MapEntityStoreMixin.java
@@ -27,13 +27,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Stream;
-import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonException;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonReader;
 import javax.json.JsonValue;
+import javax.json.JsonWriter;
 import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.common.QualifiedName;
 import org.apache.polygene.api.entity.EntityDescriptor;
@@ -48,7 +49,7 @@ import org.apache.polygene.api.structure.Application;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.unitofwork.NoSuchEntityTypeException;
 import org.apache.polygene.api.usecase.Usecase;
-import org.apache.polygene.serialization.javaxjson.JavaxJson;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entity.EntityState;
 import org.apache.polygene.spi.entity.EntityStatus;
 import org.apache.polygene.spi.entitystore.DefaultEntityStoreUnitOfWork;
@@ -59,6 +60,8 @@ import 
org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
 import org.apache.polygene.spi.entitystore.StateCommitter;
 import org.apache.polygene.spi.serialization.JsonSerialization;
 
+import static 
org.apache.polygene.api.entity.EntityReference.parseEntityReference;
+
 /**
  * Implementation of EntityStore that works with an implementation of 
MapEntityStore.
  *
@@ -82,6 +85,9 @@ public class MapEntityStoreMixin
     @Service
     private JsonSerialization jsonSerialization;
 
+    @Service
+    private JavaxJsonFactories jsonFactories;
+
     @Optional
     @Service
     private Migration migration;
@@ -137,10 +143,9 @@ public class MapEntityStoreMixin
     @Override
     public synchronized String versionOf( EntityStoreUnitOfWork uow, 
EntityReference reference )
     {
-        try
+        try( JsonReader jsonReader = 
jsonFactories.readerFactory().createReader( mapEntityStore.get( reference ) ) )
         {
-            Reader in = mapEntityStore.get( reference );
-            return Json.createReader( in ).readObject().getString( 
JSONKeys.VERSION );
+            return jsonReader.readObject().getString( JSONKeys.VERSION );
         }
         catch( EntityStoreException ex )
         {
@@ -312,56 +317,53 @@ public class MapEntityStoreMixin
     {
         try
         {
-            JsonObjectBuilder json = Json.createObjectBuilder();
+            JsonObjectBuilder json = 
jsonFactories.builderFactory().createObjectBuilder();
             json.add( JSONKeys.IDENTITY, 
state.entityReference().identity().toString() );
             json.add( JSONKeys.APPLICATION_VERSION, application.version() );
             json.add( JSONKeys.TYPE, 
state.entityDescriptor().primaryType().getName() );
             json.add( JSONKeys.VERSION, version );
             json.add( JSONKeys.MODIFIED, lastModified.toEpochMilli() );
-            JsonObjectBuilder properties = Json.createObjectBuilder();
+            JsonObjectBuilder valueBuilder = 
jsonFactories.builderFactory().createObjectBuilder();
             EntityDescriptor entityType = state.entityDescriptor();
             entityType.state().properties().forEach(
                 persistentProperty ->
                 {
                     Object value = state.properties().get( 
persistentProperty.qualifiedName() );
                     JsonValue jsonValue = jsonSerialization.toJson( value );
-                    properties.add( persistentProperty.qualifiedName().name(), 
jsonValue );
+                    valueBuilder.add( 
persistentProperty.qualifiedName().name(), jsonValue );
                 } );
-            json.add( JSONKeys.PROPERTIES, properties.build() );
 
-            JsonObjectBuilder associations = Json.createObjectBuilder();
             for( Map.Entry<QualifiedName, EntityReference> entry : 
state.associations().entrySet() )
             {
                 EntityReference value = entry.getValue();
-                associations.add( entry.getKey().name(), value == null ? null 
: value.identity().toString() );
+                valueBuilder.add( entry.getKey().name(), value == null ? null 
: value.identity().toString() );
             }
-            json.add( JSONKeys.ASSOCIATIONS, associations.build() );
 
-            JsonObjectBuilder manyAssociations = Json.createObjectBuilder();
             for( Map.Entry<QualifiedName, List<EntityReference>> entry : 
state.manyAssociations().entrySet() )
             {
-                JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+                JsonArrayBuilder arrayBuilder = 
jsonFactories.builderFactory().createArrayBuilder();
                 for( EntityReference entityReference : entry.getValue() )
                 {
                     arrayBuilder.add( entityReference.identity().toString() );
                 }
-                manyAssociations.add( entry.getKey().name(), 
arrayBuilder.build() );
+                valueBuilder.add( entry.getKey().name(), arrayBuilder.build() 
);
             }
-            json.add( JSONKeys.MANY_ASSOCIATIONS, manyAssociations.build() );
 
-            JsonObjectBuilder namedAssociations = Json.createObjectBuilder();
             for( Map.Entry<QualifiedName, Map<String, EntityReference>> entry 
: state.namedAssociations().entrySet() )
             {
-                JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+                JsonObjectBuilder objectBuilder = 
jsonFactories.builderFactory().createObjectBuilder();
                 for( Map.Entry<String, EntityReference> namedRef : 
entry.getValue().entrySet() )
                 {
                     objectBuilder.add( namedRef.getKey(), 
namedRef.getValue().identity().toString() );
                 }
-                namedAssociations.add( entry.getKey().name(), 
objectBuilder.build() );
+                valueBuilder.add( entry.getKey().name(), objectBuilder.build() 
);
             }
-            json.add( JSONKeys.NAMED_ASSOCIATIONS, namedAssociations.build() );
+            json.add( JSONKeys.VALUE, valueBuilder.build() );
             JsonObject jsonState = json.build();
-            Json.createWriter( writer ).write( jsonState );
+            try( JsonWriter jsonWriter = 
jsonFactories.writerFactory().createWriter( writer ) )
+            {
+                jsonWriter.write( jsonState );
+            }
         }
         catch( Exception e )
         {
@@ -372,10 +374,10 @@ public class MapEntityStoreMixin
     protected EntityState readEntityState( ModuleDescriptor module, Reader 
entityState )
         throws EntityStoreException
     {
-        try
+        try( JsonReader jsonReader = 
jsonFactories.readerFactory().createReader( entityState ) )
         {
-            JsonObject parsedState = Json.createReader( entityState 
).readObject();
-            JsonObjectBuilder jsonStateBuilder = JavaxJson.toBuilder( 
parsedState );
+            JsonObject parsedState = jsonReader.readObject();
+            JsonObjectBuilder jsonStateBuilder = jsonFactories.cloneBuilder( 
parsedState );
             final EntityStatus[] status = { EntityStatus.LOADED };
 
             String version = parsedState.getString( JSONKeys.VERSION );
@@ -414,13 +416,13 @@ public class MapEntityStoreMixin
             }
 
             Map<QualifiedName, Object> properties = new HashMap<>();
-            JsonObject props = state.getJsonObject( JSONKeys.PROPERTIES );
+            JsonObject valueState = state.getJsonObject( JSONKeys.VALUE );
             entityDescriptor.state().properties().forEach(
                 property ->
                 {
                     try
                     {
-                        JsonValue jsonValue = props.get( 
property.qualifiedName().name() );
+                        JsonValue jsonValue = valueState.get( 
property.qualifiedName().name() );
                         Object value = jsonSerialization.fromJson( module, 
property.valueType(), jsonValue );
                         properties.put( property.qualifiedName(), value );
                     }
@@ -434,16 +436,15 @@ public class MapEntityStoreMixin
                 } );
 
             Map<QualifiedName, EntityReference> associations = new HashMap<>();
-            JsonObject assocs = state.getJsonObject( JSONKeys.ASSOCIATIONS );
             entityDescriptor.state().associations().forEach(
                 association ->
                 {
                     try
                     {
-                        String jsonValue = assocs.getString( 
association.qualifiedName().name(), null );
+                        String jsonValue = valueState.getString( 
association.qualifiedName().name(), null );
                         EntityReference value = jsonValue == null
                                                 ? null
-                                                : 
EntityReference.parseEntityReference( jsonValue );
+                                                : parseEntityReference( 
jsonValue );
                         associations.put( association.qualifiedName(), value );
                     }
                     catch( JsonException e )
@@ -454,7 +455,6 @@ public class MapEntityStoreMixin
                     }
                 } );
 
-            JsonObject manyAssocs = state.getJsonObject( 
JSONKeys.MANY_ASSOCIATIONS );
             Map<QualifiedName, List<EntityReference>> manyAssociations = new 
HashMap<>();
             entityDescriptor.state().manyAssociations().forEach(
                 association ->
@@ -462,13 +462,13 @@ public class MapEntityStoreMixin
                     List<EntityReference> references = new ArrayList<>();
                     try
                     {
-                        JsonArray jsonValues = manyAssocs.getJsonArray( 
association.qualifiedName().name() );
+                        JsonArray jsonValues = valueState.getJsonArray( 
association.qualifiedName().name() );
                         for( int i = 0; i < jsonValues.size(); i++ )
                         {
                             String jsonValue = jsonValues.getString( i, null );
                             EntityReference value = jsonValue == null
                                                     ? null
-                                                    : 
EntityReference.parseEntityReference( jsonValue );
+                                                    : parseEntityReference( 
jsonValue );
                             references.add( value );
                         }
                         manyAssociations.put( association.qualifiedName(), 
references );
@@ -480,7 +480,6 @@ public class MapEntityStoreMixin
                     }
                 } );
 
-            JsonObject namedAssocs = state.getJsonObject( 
JSONKeys.NAMED_ASSOCIATIONS );
             Map<QualifiedName, Map<String, EntityReference>> namedAssociations 
= new HashMap<>();
             entityDescriptor.state().namedAssociations().forEach(
                 association ->
@@ -488,13 +487,13 @@ public class MapEntityStoreMixin
                     Map<String, EntityReference> references = new 
LinkedHashMap<>();
                     try
                     {
-                        JsonObject jsonValues = namedAssocs.getJsonObject( 
association.qualifiedName().name() );
+                        JsonObject jsonValues = valueState.getJsonObject( 
association.qualifiedName().name() );
                         for( String name : jsonValues.keySet() )
                         {
                             String value = jsonValues.getString( name, null );
                             EntityReference ref = value == null
                                                   ? null
-                                                  : 
EntityReference.parseEntityReference( value );
+                                                  : parseEntityReference( 
value );
                             references.put( name, ref );
                         }
                         namedAssociations.put( association.qualifiedName(), 
references );
@@ -526,9 +525,10 @@ public class MapEntityStoreMixin
     @Override
     public JsonObject jsonStateOf( String id )
     {
-        try( Reader reader = mapEntityStore.get( 
EntityReference.parseEntityReference( id ) ) )
+        try( JsonReader reader = jsonFactories.readerFactory()
+                                              .createReader( 
mapEntityStore.get( parseEntityReference( id ) ) ) )
         {
-            return Json.createReader( reader ).readObject();
+            return reader.readObject();
         }
         catch( EntityStoreException ex )
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractDeserializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractDeserializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractDeserializer.java
index 4edd044..0b604aa 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractDeserializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractDeserializer.java
@@ -18,17 +18,16 @@
 package org.apache.polygene.spi.serialization;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStream;
-import java.io.ObjectInputStream;
 import java.io.Reader;
 import java.io.StringReader;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
+import org.apache.polygene.api.composite.AmbiguousTypeException;
+import 
org.apache.polygene.api.composite.StatefulAssociationCompositeDescriptor;
 import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.serialization.Deserializer;
-import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.CollectionType;
 import org.apache.polygene.api.type.MapType;
@@ -163,15 +162,23 @@ public abstract class AbstractDeserializer implements 
Deserializer
         return ( (ModuleSpi) module.instance() 
).valueTypeFactory().valueTypeOf( module, type );
     }
 
-    protected Object deserializeJava( byte[] bytes )
+    protected final StatefulAssociationCompositeDescriptor 
statefulCompositeDescriptorFor( ModuleDescriptor module,
+                                                                               
            String typeName )
     {
-        try( ObjectInputStream oin = new ObjectInputStream( new 
ByteArrayInputStream( bytes ) ) )
+        StatefulAssociationCompositeDescriptor descriptor = null;
+        try
         {
-            return oin.readObject();
+            descriptor = module.valueDescriptor( typeName );
         }
-        catch( IOException | ClassNotFoundException ex )
+        catch( AmbiguousTypeException ex ) { }
+        if( descriptor == null )
         {
-            throw new SerializationException( "Unable to deserialize using 
Java serialization", ex );
+            try
+            {
+                descriptor = module.entityDescriptor( typeName );
+            }
+            catch( AmbiguousTypeException ex ) { }
         }
+        return descriptor;
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractSerializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractSerializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractSerializer.java
index 4db3548..3269adb 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractSerializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractSerializer.java
@@ -18,8 +18,6 @@
 package org.apache.polygene.spi.serialization;
 
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.StringWriter;
 import java.io.Writer;
@@ -27,7 +25,6 @@ import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import org.apache.polygene.api.common.Optional;
-import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.serialization.Serializer;
 
 /**
@@ -154,19 +151,4 @@ public abstract class AbstractSerializer implements 
Serializer
     {
         return Stream.of( objects ).map( object -> toBytes( Options.DEFAULT, 
object ) );
     }
-
-    protected byte[] serializeJava( Object object )
-    {
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        try( ObjectOutputStream out = new ObjectOutputStream( bout ) )
-        {
-            out.writeUnshared( object );
-            out.flush();
-            return bout.toByteArray();
-        }
-        catch( IOException ex )
-        {
-            throw new SerializationException( "Unable to serialize using Java 
serialization", ex );
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
index fdec10c..61a39c9 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
@@ -21,6 +21,7 @@ import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import javax.json.JsonValue;
+import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.serialization.Deserializer;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.ValueType;
@@ -31,7 +32,7 @@ import org.apache.polygene.spi.module.ModuleSpi;
  */
 public interface JsonDeserializer extends Deserializer
 {
-    <T> T fromJson( ModuleDescriptor module, ValueType valueType, JsonValue 
state );
+    <T> T fromJson( ModuleDescriptor module, ValueType valueType, @Optional 
JsonValue state );
 
     default <T> Function<JsonValue, T> fromJsonFunction( ModuleDescriptor 
module, ValueType valueType )
     {
@@ -53,7 +54,7 @@ public interface JsonDeserializer extends Deserializer
         return fromJsonEach( module, valueType, Stream.of( states ) );
     }
 
-    default <T> T fromJson( ModuleDescriptor module, Class<T> type, JsonValue 
state )
+    default <T> T fromJson( ModuleDescriptor module, Class<T> type, @Optional 
JsonValue state )
     {
         // TODO Remove (ModuleSpi) cast
         ValueType valueType = ( (ModuleSpi) module.instance() 
).valueTypeFactory().valueTypeOf( module, type );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
index 4ea4fe1..cc5ddc6 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
@@ -20,6 +20,7 @@ package org.apache.polygene.spi.serialization;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
+import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.serialization.Deserializer;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.ValueType;
@@ -31,7 +32,7 @@ import org.w3c.dom.Node;
  */
 public interface XmlDeserializer extends Deserializer
 {
-    <T> T fromXml( ModuleDescriptor module, ValueType valueType, Node state );
+    <T> T fromXml( ModuleDescriptor module, ValueType valueType, @Optional 
Node state );
 
     default <T> Function<Node, T> fromXmlFunction( ModuleDescriptor module, 
ValueType valueType )
     {
@@ -53,7 +54,7 @@ public interface XmlDeserializer extends Deserializer
         return fromXmlEach( module, valueType, Stream.of( states ) );
     }
 
-    default <T> T fromXml( ModuleDescriptor module, Class<T> type, Node state )
+    default <T> T fromXml( ModuleDescriptor module, Class<T> type, @Optional 
Node state )
     {
         // TODO Remove (ModuleSpi) cast
         ValueType valueType = ( (ModuleSpi) module.instance() 
).valueTypeFactory().valueTypeOf( module, type );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java
 
b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java
index 67af1f8..a55c642 100644
--- 
a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java
+++ 
b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java
@@ -25,8 +25,13 @@ import javax.json.Json;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.injection.scope.Service;
 import org.apache.polygene.api.time.SystemTime;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entity.EntityStatus;
+import org.apache.polygene.spi.serialization.JsonSerialization;
+import org.apache.polygene.test.AbstractPolygeneTest;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -34,28 +39,36 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertThat;
 
-public class JSONManyAssociationStateTest
+public class JSONManyAssociationStateTest extends AbstractPolygeneTest
 {
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+    }
+
+    @Service
+    private JsonSerialization serialization;
+
+    @Service
+    private JavaxJsonFactories jsonFactories;
 
     @Test
     public void 
givenEmptyJSONManyAssociationStateWhenAddingTwoRefsAtZeroIndexExpectCorrectOrder()
     {
         // Fake JSONManyAssociationState
         JsonObjectBuilder builder = Json.createObjectBuilder();
-        builder.add( JSONKeys.PROPERTIES, Json.createObjectBuilder().build() );
-        builder.add( JSONKeys.ASSOCIATIONS, Json.createObjectBuilder().build() 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
+        builder.add( JSONKeys.VALUE, Json.createObjectBuilder().build() );
         JsonObject state = builder.build();
-        JSONEntityState entityState = new JSONEntityState( null,
-                                                           null,
+        JSONEntityState entityState = new JSONEntityState( module,
+                                                           serialization,
+                                                           jsonFactories,
                                                            "0",
                                                            SystemTime.now(),
                                                            
EntityReference.parseEntityReference( "123" ),
                                                            EntityStatus.NEW,
                                                            null,
                                                            state );
-        JSONManyAssociationState jsonState = new JSONManyAssociationState( 
entityState, "under-test" );
+        JSONManyAssociationState jsonState = new JSONManyAssociationState( 
jsonFactories, entityState, "under-test" );
 
         jsonState.add( 0, EntityReference.parseEntityReference( "first" ) );
         jsonState.add( 0, EntityReference.parseEntityReference( "second" ) );
@@ -68,20 +81,18 @@ public class JSONManyAssociationStateTest
     {
         // Fake JSONManyAssociationState
         JsonObjectBuilder builder = Json.createObjectBuilder();
-        builder.add( JSONKeys.PROPERTIES, Json.createObjectBuilder().build() );
-        builder.add( JSONKeys.ASSOCIATIONS, Json.createObjectBuilder().build() 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
+        builder.add( JSONKeys.VALUE, Json.createObjectBuilder().build() );
         JsonObject state = builder.build();
-        JSONEntityState entityState = new JSONEntityState( null,
-                                                           null,
+        JSONEntityState entityState = new JSONEntityState( module,
+                                                           serialization,
+                                                           jsonFactories,
                                                            "0",
                                                            SystemTime.now(),
                                                            
EntityReference.parseEntityReference( "123" ),
                                                            EntityStatus.NEW,
                                                            null,
                                                            state );
-        JSONManyAssociationState jsonState = new JSONManyAssociationState( 
entityState, "under-test" );
+        JSONManyAssociationState jsonState = new JSONManyAssociationState( 
jsonFactories, entityState, "under-test" );
 
         assertThat( jsonState.contains( EntityReference.parseEntityReference( 
"NOT_PRESENT" ) ), is( false ) );
 
@@ -132,8 +143,8 @@ public class JSONManyAssociationStateTest
         }
         assertThat( refList.isEmpty(), is( false ) );
         assertArrayEquals( new String[]
-        {
-            "C", "B", "A", "0", "2", "1"
-        }, refList.toArray() );
+                               {
+                                   "C", "B", "A", "0", "2", "1"
+                               }, refList.toArray() );
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java
 
b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java
index 8a4b7db..5bab0c1 100644
--- 
a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java
+++ 
b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java
@@ -25,8 +25,13 @@ import javax.json.Json;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.injection.scope.Service;
 import org.apache.polygene.api.time.SystemTime;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entity.EntityStatus;
+import org.apache.polygene.spi.serialization.JsonSerialization;
+import org.apache.polygene.test.AbstractPolygeneTest;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -34,27 +39,36 @@ import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
-public class JsonNamedAssociationStateTest
+public class JsonNamedAssociationStateTest extends AbstractPolygeneTest
 {
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+    }
+
+    @Service
+    private JsonSerialization serialization;
+
+    @Service
+    private JavaxJsonFactories jsonFactories;
+
     @Test
     public void 
givenJsonNamedAssociationStateWhenChangingReferencesExpectCorrectBehavior()
     {
         // Fake JsonNamedAssociationState
         JsonObjectBuilder builder = Json.createObjectBuilder();
-        builder.add( JSONKeys.PROPERTIES, Json.createObjectBuilder().build() );
-        builder.add( JSONKeys.ASSOCIATIONS, Json.createObjectBuilder().build() 
);
-        builder.add( JSONKeys.MANY_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
-        builder.add( JSONKeys.NAMED_ASSOCIATIONS, 
Json.createObjectBuilder().build() );
+        builder.add( JSONKeys.VALUE, Json.createObjectBuilder().build() );
         JsonObject state = builder.build();
-        JSONEntityState entityState = new JSONEntityState( null,
-                                                           null,
+        JSONEntityState entityState = new JSONEntityState( module,
+                                                           serialization,
+                                                           jsonFactories,
                                                            "0",
                                                            SystemTime.now(),
                                                            
EntityReference.parseEntityReference( "123" ),
                                                            EntityStatus.NEW,
                                                            null,
                                                            state );
-        JSONNamedAssociationState jsonState = new JSONNamedAssociationState( 
entityState, "under-test" );
+        JSONNamedAssociationState jsonState = new JSONNamedAssociationState( 
jsonFactories, entityState, "under-test" );
 
 
         assertThat( jsonState.containsName( "foo" ), is( false ) );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractPlainValueSerializationTest.java
----------------------------------------------------------------------
diff --git 
a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractPlainValueSerializationTest.java
 
b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractPlainValueSerializationTest.java
index cd4bc37..4b34b64 100644
--- 
a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractPlainValueSerializationTest.java
+++ 
b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractPlainValueSerializationTest.java
@@ -36,6 +36,7 @@ import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.Service;
 import org.apache.polygene.api.serialization.Converter;
 import org.apache.polygene.api.serialization.Serialization;
+import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.type.EnumType;
 import org.apache.polygene.api.type.ValueType;
 import org.apache.polygene.bootstrap.ModuleAssembly;
@@ -45,9 +46,11 @@ import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.Matchers.startsWith;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.hamcrest.core.IsNot.not;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
 
 /**
  * Assert that Serialization behaviour on plain values is correct.
@@ -76,6 +79,20 @@ public abstract class AbstractPlainValueSerializationTest 
extends AbstractPolyge
     protected abstract String getSingleStringRawState( String state ) throws 
Exception;
 
     @Test
+    public void dontKnowHowToSerializeJavaLangObject()
+    {
+        try
+        {
+            serialization.serialize( new Object() );
+            fail( "serialization.serialize( new Object() ) should have failed" 
);
+        }
+        catch( SerializationException ex )
+        {
+            assertThat( ex.getMessage(), startsWith( "Don't know how to 
serialize" ) );
+        }
+    }
+
+    @Test
     public void givenNullValueWhenSerializingAndDeserializingExpectNull()
     {
         String output = serialization.serialize( null );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
----------------------------------------------------------------------
diff --git 
a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
 
b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
index 221a788..3741fd2 100644
--- 
a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
+++ 
b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
@@ -45,6 +45,8 @@ import org.apache.polygene.api.injection.scope.Structure;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.mixin.Mixins;
 import org.apache.polygene.api.property.Property;
+import org.apache.polygene.api.serialization.ConvertedBy;
+import org.apache.polygene.api.serialization.JavaSerializationConverter;
 import org.apache.polygene.api.serialization.Serialization;
 import org.apache.polygene.api.structure.Module;
 import org.apache.polygene.api.unitofwork.UnitOfWork;
@@ -91,12 +93,13 @@ public abstract class 
AbstractValueCompositeSerializationTest
     @Override
     public void assemble( ModuleAssembly module )
     {
+        module.objects( JavaSerializationConverter.class );
         module.values( Some.class, SomeExtended.class, SomeShuffled.class,
                        AnotherValue.class, FooValue.class, 
CustomFooValue.class,
                        SpecificCollection.class /*, SpecificValue.class, 
GenericValue.class */ );
+        module.entities( Some.class, BarEntity.class );
 
         new EntityTestAssembler().visibleIn( Visibility.layer ).assemble( 
module.layer().module( "persistence" ) );
-        module.entities( Some.class, BarEntity.class );
     }
 
     @Structure
@@ -145,6 +148,45 @@ public abstract class 
AbstractValueCompositeSerializationTest
     }
 
     @Test
+    public void 
givenEntityCompositeWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork() )
+        {
+            Some some = buildSomeEntity( moduleInstance, uow, "23" );
+
+            // Serialize using injected service
+            String stateString = serialization.serialize( some );
+            System.out.println( stateString );
+
+            // Deserialize using Module API
+            Some some2 = moduleInstance.newValueFromSerializedState( 
Some.class, stateString );
+
+            assertThat( "Map<String, Integer>",
+                        some2.stringIntMap().get().get( "foo" ),
+                        equalTo( 42 ) );
+            assertThat( "Map<String, Value>",
+                        some2.stringValueMap().get().get( "foo" 
).internalVal(),
+                        equalTo( "Bar" ) );
+
+            assertThat( "Nested Entities",
+                        some2.barAssociation().get().cathedral().get(),
+                        equalTo( "bazar in barAssociation" ) );
+
+            assertThat( "Polymorphic deserialization of value type NOT 
extending ValueComposite",
+                        some.customFoo().get() instanceof CustomFooValue,
+                        is( true ) );
+            assertThat( "Polymorphic deserialization of value type extending 
ValueComposite",
+                        some.customFooValue().get() instanceof CustomFooValue,
+                        is( true ) );
+
+            assertThat( "Value equality", some, equalTo( some2 ) );
+
+            uow.complete();
+        }
+    }
+
+    @Test
     public void canDeserializeUsingSuperTypeWithLessState()
     {
         try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork() )
@@ -255,6 +297,15 @@ public abstract class 
AbstractValueCompositeSerializationTest
                     createdValue, equalTo( loadedValue ) );
     }
 
+    protected static Some buildSomeEntity( Module module, UnitOfWork uow, 
String identity )
+    {
+        EntityBuilder<Some> builder = uow.newEntityBuilder( Some.class );
+        Some proto = builder.instance();
+        proto.identity().set( StringIdentity.fromString( identity ) );
+        setSomeValueState( module, uow, proto );
+        return builder.newInstance();
+    }
+
     /**
      * @return a Some ValueComposite whose state is populated with test data.
      */
@@ -436,7 +487,7 @@ public abstract class 
AbstractValueCompositeSerializationTest
         @Optional
         Property<Byte[]> byteArrayNull();
 
-        Property<Object> serializable();
+        Property<SerializableObject> serializable();
 
         Property<Foo> foo();
 
@@ -591,6 +642,7 @@ public abstract class 
AbstractValueCompositeSerializationTest
     {
     }
 
+    @ConvertedBy( JavaSerializationConverter.class )
     public static class SerializableObject
         implements Serializable
     {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b2ff271b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SQLMapEntityStoreMixin.java
----------------------------------------------------------------------
diff --git 
a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SQLMapEntityStoreMixin.java
 
b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SQLMapEntityStoreMixin.java
index f1a852f..682a5f7 100644
--- 
a/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SQLMapEntityStoreMixin.java
+++ 
b/extensions/entitystore-sql/src/main/java/org/apache/polygene/entitystore/sql/SQLMapEntityStoreMixin.java
@@ -26,7 +26,6 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Stream;
-import javax.json.Json;
 import javax.sql.DataSource;
 import liquibase.Contexts;
 import liquibase.Liquibase;
@@ -42,6 +41,7 @@ import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.service.ServiceActivation;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.library.sql.liquibase.LiquibaseService;
+import org.apache.polygene.serialization.javaxjson.JavaxJsonFactories;
 import org.apache.polygene.spi.entitystore.EntityNotFoundException;
 import org.apache.polygene.spi.entitystore.helpers.JSONKeys;
 import org.apache.polygene.spi.entitystore.helpers.MapEntityStore;
@@ -69,6 +69,9 @@ public class SQLMapEntityStoreMixin
     @Service
     private LiquibaseService liquibaseService;
 
+    @Service
+    private JavaxJsonFactories jsonFactories;
+
     @Uses
     private ServiceDescriptor descriptor;
 
@@ -194,8 +197,9 @@ public class SQLMapEntityStoreMixin
                     {
                         super.close();
                         String state = toString();
-                        String version = Json.createReader( new StringReader( 
state ) ).readObject()
-                                             .getString( JSONKeys.VERSION );
+                        String version = 
jsonFactories.readerFactory().createReader( new StringReader( state ) )
+                                                      .readObject()
+                                                      .getString( 
JSONKeys.VERSION );
                         operations.add(
                             dsl.insertInto( table )
                                .columns( identityColumn, versionColumn, 
stateColumn )

Reply via email to