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 2017/03/13 10:35:20 UTC

[28/50] [abbrv] polygene-java git commit: New (de)serialization API and SPI & new implementations

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java b/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java
deleted file mode 100644
index dbe658f..0000000
--- a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *
- */
-package org.apache.polygene.valueserialization.orgjson;
-
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import org.json.JSONWriter;
-import org.apache.polygene.spi.value.ValueSerializerAdapter;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializer.OrgJsonOutput;
-
-/**
- * ValueSerializer producing Values state as JSON documents using org.json.
- */
-public class OrgJsonValueSerializer
-    extends ValueSerializerAdapter<OrgJsonOutput>
-{
-
-    /**
-     * Helper to pass around the Writer alongside the JSONWriter so we can flush it onSerializationEnd.
-     *
-     * This is needed because the org.json package do not allow to get a handle on the Writer from a JSONWriter.
-     */
-    public static class OrgJsonOutput
-    {
-
-        private final Writer writer;
-        private final JSONWriter json;
-
-        private OrgJsonOutput( Writer writer, JSONWriter json )
-        {
-            this.writer = writer;
-            this.json = json;
-        }
-    }
-
-    //
-    // Serialization
-    //
-    @Override
-    protected OrgJsonOutput adaptOutput( OutputStream output )
-        throws Exception
-    {
-        Writer writer = new OutputStreamWriter( output, "UTF-8" );
-        JSONWriter json = new JSONWriter( writer );
-        return new OrgJsonOutput( writer, json );
-    }
-
-    @Override
-    protected void onSerializationEnd( Object object, OrgJsonOutput output )
-        throws Exception
-    {
-        output.writer.flush();
-    }
-
-    @Override
-    protected void onArrayStart( OrgJsonOutput output )
-        throws Exception
-    {
-        output.json.array();
-    }
-
-    @Override
-    protected void onArrayEnd( OrgJsonOutput output )
-        throws Exception
-    {
-        output.json.endArray();
-    }
-
-    @Override
-    protected void onObjectStart( OrgJsonOutput output )
-        throws Exception
-    {
-        output.json.object();
-    }
-
-    @Override
-    protected void onObjectEnd( OrgJsonOutput output )
-        throws Exception
-    {
-        output.json.endObject();
-    }
-
-    @Override
-    protected void onFieldStart( OrgJsonOutput output, String fieldName )
-        throws Exception
-    {
-        output.json.key( fieldName );
-    }
-
-    @Override
-    protected void onValue( OrgJsonOutput output, Object value )
-        throws Exception
-    {
-        output.json.value( value );
-    }
-}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html b/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html
deleted file mode 100644
index 4799b58..0000000
--- a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-  ~  Licensed to the Apache Software Foundation (ASF) under one
-  ~  or more contributor license agreements.  See the NOTICE file
-  ~  distributed with this work for additional information
-  ~  regarding copyright ownership.  The ASF licenses this file
-  ~  to you under the Apache License, Version 2.0 (the
-  ~  "License"); you may not use this file except in compliance
-  ~  with the License.  You may obtain a copy of the License at
-  ~
-  ~       http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~  Unless required by applicable law or agreed to in writing, software
-  ~  distributed under the License is distributed on an "AS IS" BASIS,
-  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~  See the License for the specific language governing permissions and
-  ~  limitations under the License.
-  ~
-  ~
-  -->
-<html>
-    <body>
-        <h2>org.json Value Serialization.</h2>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java
----------------------------------------------------------------------
diff --git a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java
index 718e3b7..831cc45 100644
--- a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java
+++ b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java
@@ -23,10 +23,10 @@ import org.apache.polygene.api.identity.StringIdentity;
 import org.apache.polygene.api.injection.scope.Service;
 import org.apache.polygene.api.property.Property;
 import org.apache.polygene.api.service.qualifier.Tagged;
+import org.apache.polygene.api.serialization.Serialization;
 import org.apache.polygene.api.unitofwork.UnitOfWork;
 import org.apache.polygene.api.usecase.UsecaseBuilder;
 import org.apache.polygene.api.value.ValueBuilder;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.test.AbstractPolygeneTest;
 import org.apache.polygene.test.EntityTestAssembler;
@@ -43,20 +43,13 @@ public class Polygene142Test extends AbstractPolygeneTest
     }
 
     @Service
-    @Tagged( ValueSerialization.Formats.JSON )
-    private ValueSerialization serialization;
+    @Tagged( Serialization.Formats.JSON )
+    private Serialization serialization;
 
     @Test
     public void polygene142RegressionTest()
         throws Exception
     {
-        if( getClass().getName().equals(
-            "org.apache.polygene.valueserialization.stax.StaxPlainValueSerializationTest" ) )
-        {
-            // This test is disabled, as this test expect a JSON capable serializer as it uses
-            // the JSONMapEntityStoreMixin in MemoryEntityStore.
-            return;
-        }
         Regression142Type value;
         {
             ValueBuilder<Regression142Type> builder = valueBuilderFactory.newValueBuilder( Regression142Type.class );
@@ -85,7 +78,7 @@ public class Polygene142Test extends AbstractPolygeneTest
                 }
             }
             {
-                try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( UsecaseBuilder.newUsecase( "create" ) ) )
+                try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( UsecaseBuilder.newUsecase( "read" ) ) )
                 {
                     value = uow.get( Regression142Type.class, valueId );
                     System.out.println( value.price().get() );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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 9538042..67af1f8 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
@@ -21,12 +21,12 @@ package org.apache.polygene.spi.entitystore.helpers;
 
 import java.util.ArrayList;
 import java.util.List;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
 import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.time.SystemTime;
 import org.apache.polygene.spi.entity.EntityStatus;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -39,14 +39,14 @@ public class JSONManyAssociationStateTest
 
     @Test
     public void givenEmptyJSONManyAssociationStateWhenAddingTwoRefsAtZeroIndexExpectCorrectOrder()
-        throws JSONException
     {
         // Fake JSONManyAssociationState
-        JSONObject state = new JSONObject();
-        state.put( JSONKeys.PROPERTIES, new JSONObject() );
-        state.put( JSONKeys.ASSOCIATIONS, new JSONObject() );
-        state.put( JSONKeys.MANY_ASSOCIATIONS, new JSONObject() );
-        state.put( JSONKeys.NAMED_ASSOCIATIONS, new JSONObject() );
+        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() );
+        JsonObject state = builder.build();
         JSONEntityState entityState = new JSONEntityState( null,
                                                            null,
                                                            "0",
@@ -55,7 +55,7 @@ public class JSONManyAssociationStateTest
                                                            EntityStatus.NEW,
                                                            null,
                                                            state );
-        JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, new JSONArray() );
+        JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, "under-test" );
 
         jsonState.add( 0, EntityReference.parseEntityReference( "first" ) );
         jsonState.add( 0, EntityReference.parseEntityReference( "second" ) );
@@ -65,14 +65,14 @@ public class JSONManyAssociationStateTest
 
     @Test
     public void givenJSONManyAssociationStateWhenChangingReferencesExpectCorrectBehavior()
-        throws JSONException
     {
         // Fake JSONManyAssociationState
-        JSONObject state = new JSONObject();
-        state.put( JSONKeys.PROPERTIES, new JSONObject() );
-        state.put( JSONKeys.ASSOCIATIONS, new JSONObject() );
-        state.put( JSONKeys.MANY_ASSOCIATIONS, new JSONObject() );
-        state.put( JSONKeys.NAMED_ASSOCIATIONS, new JSONObject() );
+        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() );
+        JsonObject state = builder.build();
         JSONEntityState entityState = new JSONEntityState( null,
                                                            null,
                                                            "0",
@@ -81,7 +81,7 @@ public class JSONManyAssociationStateTest
                                                            EntityStatus.NEW,
                                                            null,
                                                            state );
-        JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, new JSONArray() );
+        JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, "under-test" );
 
         assertThat( jsonState.contains( EntityReference.parseEntityReference( "NOT_PRESENT" ) ), is( false ) );
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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
new file mode 100644
index 0000000..8a4b7db
--- /dev/null
+++ b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java
@@ -0,0 +1,104 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.spi.entitystore.helpers;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.time.SystemTime;
+import org.apache.polygene.spi.entity.EntityStatus;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class JsonNamedAssociationStateTest
+{
+    @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() );
+        JsonObject state = builder.build();
+        JSONEntityState entityState = new JSONEntityState( null,
+                                                           null,
+                                                           "0",
+                                                           SystemTime.now(),
+                                                           EntityReference.parseEntityReference( "123" ),
+                                                           EntityStatus.NEW,
+                                                           null,
+                                                           state );
+        JSONNamedAssociationState jsonState = new JSONNamedAssociationState( entityState, "under-test" );
+
+
+        assertThat( jsonState.containsName( "foo" ), is( false ) );
+
+        jsonState.put( "foo", EntityReference.parseEntityReference( "0" ) );
+        jsonState.put( "bar", EntityReference.parseEntityReference( "1" ) );
+        jsonState.put( "bazar", EntityReference.parseEntityReference( "2" ) );
+
+        assertThat( jsonState.containsName( "bar" ), is( true ) );
+
+        assertThat( jsonState.get( "foo" ).identity().toString(), equalTo( "0" ) );
+        assertThat( jsonState.get( "bar" ).identity().toString(), equalTo( "1" ) );
+        assertThat( jsonState.get( "bazar" ).identity().toString(), equalTo( "2" ) );
+
+        assertThat( jsonState.count(), equalTo( 3 ) );
+
+        jsonState.remove( "bar" );
+
+        assertThat( jsonState.count(), equalTo( 2 ) );
+        assertThat( jsonState.containsName( "bar" ), is( false ) );
+        assertThat( jsonState.get( "foo" ).identity().toString(), equalTo( "0" ) );
+        assertThat( jsonState.get( "bazar" ).identity().toString(), equalTo( "2" ) );
+
+        jsonState.put( "bar", EntityReference.parseEntityReference( "1" ) );
+
+        assertThat( jsonState.count(), equalTo( 3 ) );
+
+        jsonState.put( "oof", EntityReference.parseEntityReference( "A" ) );
+        jsonState.put( "rab", EntityReference.parseEntityReference( "B" ) );
+        jsonState.put( "razab", EntityReference.parseEntityReference( "C" ) );
+
+        assertThat( jsonState.count(), equalTo( 6 ) );
+
+        assertThat( jsonState.get( "razab" ).identity().toString(), equalTo( "C" ) );
+        assertThat( jsonState.get( "rab" ).identity().toString(), equalTo( "B" ) );
+        assertThat( jsonState.get( "oof" ).identity().toString(), equalTo( "A" ) );
+
+        Map<String, String> refMap = new LinkedHashMap<>();
+        for( String name : jsonState )
+        {
+            refMap.put( name, jsonState.get( name ).identity().toString() );
+        }
+        assertThat( refMap.isEmpty(), is( false ) );
+        assertThat( refMap.keySet(), hasItems( "foo", "bar", "bazar", "oof", "rab", "razab" ) );
+        assertThat( refMap.values(), hasItems( "0", "1", "2", "A", "B", "C" ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java b/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java
index 945ea47..ec7237b 100644
--- a/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java
@@ -19,16 +19,14 @@
  */
 package org.apache.polygene.test;
 
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.Assemblers;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.bootstrap.ServiceDeclaration;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
 
 /**
- * Helper assembler that adds an in-memory EntityStore, a UUID generator, and an Entity type registry to the module
+ * Helper assembler that adds an in-memory EntityStore to the module
  */
 public class EntityTestAssembler
     extends Assemblers.VisibilityIdentity<EntityTestAssembler>
@@ -42,6 +40,5 @@ public class EntityTestAssembler
         {
             service.identifiedBy( identity() );
         }
-        module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java
index b50d96d..f8877c0 100644
--- a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java
@@ -20,7 +20,6 @@
 
 package org.apache.polygene.test.entity;
 
-import org.junit.Test;
 import org.apache.polygene.api.common.Visibility;
 import org.apache.polygene.api.configuration.Configuration;
 import org.apache.polygene.api.identity.HasIdentity;
@@ -28,12 +27,11 @@ 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.service.ServiceReference;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
 import org.apache.polygene.test.AbstractPolygeneTest;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
+import org.junit.Test;
 
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.hamcrest.core.IsNull.notNullValue;
@@ -45,14 +43,11 @@ public abstract class AbstractConfigurationDeserializationTest extends AbstractP
     public void assemble( ModuleAssembly module )
         throws AssemblyException
     {
-//        ModuleAssembly storageModule = module.layer().module( "storage" );
-        @SuppressWarnings( "UnnecessaryLocalVariable" )
-        ModuleAssembly storageModule = module; // Disable the more complex set up. The entire value serialization has gotten the deserialization type lookup problem wrong.
+        ModuleAssembly storageModule = module.layer().module( "storage" );
         module.configurations( ConfigSerializationConfig.class );
         module.values( Host.class );
         module.services( MyService.class ).identifiedBy( "configtest" );
         storageModule.services( MemoryEntityStoreService.class ).visibleIn( Visibility.layer );
-        storageModule.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java b/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java
index 30f4be7..b0121c7 100644
--- a/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java
@@ -21,13 +21,11 @@
 package org.apache.polygene.test.indexing.layered.assembly;
 
 import org.apache.polygene.api.common.Visibility;
-import org.apache.polygene.api.value.ValueSerialization;
 import org.apache.polygene.bootstrap.AssemblyException;
 import org.apache.polygene.bootstrap.LayerAssembly;
 import org.apache.polygene.bootstrap.ModuleAssembly;
 import org.apache.polygene.bootstrap.layered.ModuleAssembler;
 import org.apache.polygene.entitystore.memory.MemoryEntityStoreService;
-import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService;
 
 class PersistenceModule
     implements ModuleAssembler
@@ -37,7 +35,6 @@ class PersistenceModule
     public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
         throws AssemblyException
     {
-        module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON );
         module.services( MemoryEntityStoreService.class ).visibleIn( Visibility.application );
         return module;
     }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java
new file mode 100644
index 0000000..474ed1a
--- /dev/null
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java
@@ -0,0 +1,481 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.test.serialization;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.property.Property;
+import org.apache.polygene.api.serialization.Serialization;
+import org.apache.polygene.api.type.CollectionType;
+import org.apache.polygene.api.type.EnumType;
+import org.apache.polygene.api.type.MapType;
+import org.apache.polygene.api.type.ValueCompositeType;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.api.value.ValueBuilder;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Assert that ValueSerialization behaviour on Collections and Maps is correct.
+ */
+public class AbstractCollectionSerializationTest
+    extends AbstractPolygeneTest
+{
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.values( SomeValue.class );
+    }
+
+    @Service
+    @SuppressWarnings( "ProtectedField" )
+    protected Serialization stateSerialization;
+
+    @Test
+    public void givenPrimitiveArrayWithIntsWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        int[] primitiveArray = new int[]
+            {
+                23, 42, -23, -42
+            };
+        String output = stateSerialization.serialize( primitiveArray );
+        System.out.println( output );
+        int[] deserialized = stateSerialization.deserialize( module, int[].class, output );
+        assertArrayEquals( primitiveArray, deserialized );
+    }
+
+    @Test
+    public void givenArrayWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        Byte[] array = new Byte[]
+            {
+                9, null, -12, -12, 127, -128, 73
+            };
+        String output = stateSerialization.serialize( array );
+        System.out.println( output );
+        Byte[] deserialized = stateSerialization.deserialize( module, Byte[].class, output );
+        assertArrayEquals( array, deserialized );
+    }
+
+    @Test
+    public void givenIterableTypeWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( new AdHocIterable<>( byteCollection() ) );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.BYTE );
+        List<Byte> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( byteCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( byteCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.setOf( ValueType.BYTE );
+        Set<Byte> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( new LinkedHashSet<>( byteCollection() ), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithCharacterAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( characterCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.CHARACTER );
+        List<Character> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( characterCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithShortAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( shortCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.SHORT );
+        List<Short> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( shortCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithIntegerAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( integerCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.INTEGER );
+        List<Integer> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( integerCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithLongAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( longCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.LONG );
+        List<Long> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( longCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithFloatAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( floatCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.FLOAT );
+        List<Float> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( floatCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithDoubleAndNullElementWhenSerializingExpectCorrectJsonOutput()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( doubleCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.DOUBLE );
+        List<Double> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( doubleCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithBigIntegerAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( bigIntegerCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.BIG_INTEGER );
+        List<BigInteger> list = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( bigIntegerCollection(), list );
+    }
+
+    @Test
+    public void givenCollectionTypeWithBigDecimalAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( bigDecimalCollection() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.collectionOf( ValueType.BIG_DECIMAL );
+        Collection<BigDecimal> collection = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( bigDecimalCollection(), collection );
+    }
+
+    @Test
+    public void givenMapOfStringByteAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( stringByteMap() );
+        System.out.println( output );
+        MapType mapType = MapType.of( ValueType.STRING, ValueType.BYTE );
+        Map<String, Byte> value = stateSerialization.deserialize( module, mapType, output );
+        assertEquals( stringByteMap(), value );
+    }
+
+    @Test
+    public void givenMapOfStringListStringAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( stringMultiMap() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( ValueType.STRING );
+        MapType mapType = MapType.of( ValueType.STRING, collectionType );
+        Map<String, List<String>> value = stateSerialization.deserialize( module, mapType, output );
+        assertEquals( stringMultiMap(), value );
+    }
+
+    @Test
+    public void givenListOfMapStringStringAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( stringListOfMaps() );
+        System.out.println( output );
+        CollectionType collectionType = CollectionType.listOf( MapType.of( ValueType.STRING, ValueType.STRING ) );
+        List<Map<String, String>> value = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( stringListOfMaps(), value );
+    }
+
+    @Test
+    public void givenListOfValueCompositesAndNullElementWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        String output = stateSerialization.serialize( valueCompositesList() );
+        System.out.println( output );
+        ValueCompositeType valueType = module.valueDescriptor( SomeValue.class.getName() ).valueType();
+        CollectionType collectionType = CollectionType.listOf( valueType );
+        List<SomeValue> value = stateSerialization.deserialize( module, collectionType, output );
+        assertEquals( valueCompositesList(), value );
+    }
+
+    @Test
+    public void givenEnumSetWhenSerializingAndDeserializingExpectEquals()
+    {
+        Set<SomeEnum> enumSet = EnumSet.allOf( SomeEnum.class );
+        String output = stateSerialization.serialize( enumSet );
+        System.out.println( output );
+        CollectionType valueType = CollectionType.setOf( EnumType.of( SomeEnum.class ) );
+        Set<SomeEnum> value = stateSerialization.deserialize( module, valueType, output );
+        assertEquals( enumSet, value );
+    }
+
+    @Test
+    public void givenEnumMapWhenSerializingAndDeserializingExpectEquals()
+    {
+        EnumMap<SomeEnum, Number> enumMap = new EnumMap<>( SomeEnum.class );
+        for( SomeEnum value : SomeEnum.values() )
+        {
+            enumMap.put( value, 23 );
+        }
+        String output = stateSerialization.serialize( enumMap );
+        System.out.println( output );
+        MapType valueType = MapType.of( EnumType.of( SomeEnum.class ), ValueType.of( Integer.class ) );
+        Map<SomeEnum, Number> value = stateSerialization.deserialize( module, valueType, output );
+        assertEquals( enumMap, value );
+    }
+
+    private ArrayList<Byte> byteCollection()
+    {
+        ArrayList<Byte> value = new ArrayList<>();
+        value.add( (byte) 9 );
+        value.add( null );
+        value.add( (byte) -12 );
+        value.add( (byte) -12 );
+        value.add( (byte) 127 );
+        value.add( (byte) -128 );
+        value.add( (byte) 73 );
+        return value;
+    }
+
+    private List<Character> characterCollection()
+    {
+        List<Character> value = new ArrayList<>();
+        value.add( 'Q' );
+        value.add( 'i' );
+        value.add( null );
+        value.add( '4' );
+        value.add( 'j' );
+        return value;
+    }
+
+    private Collection<Short> shortCollection()
+    {
+        Collection<Short> value = new ArrayList<>();
+        value.add( (short) -32768 );
+        value.add( (short) 32767 );
+        value.add( (short) -82 );
+        value.add( null );
+        return value;
+    }
+
+    private Collection<Integer> integerCollection()
+    {
+        Collection<Integer> value = new ArrayList<>();
+        value.add( Integer.MAX_VALUE );
+        value.add( -283 );
+        value.add( null );
+        value.add( Integer.MIN_VALUE );
+        value.add( 238 );
+        return value;
+    }
+
+    private Collection<Long> longCollection()
+    {
+        Collection<Long> value = new ArrayList<>();
+        value.add( 98239723L );
+        value.add( -1298233L );
+        value.add( -1L );
+        value.add( 0L );
+        value.add( null );
+        value.add( 1L );
+        value.add( Long.MAX_VALUE );
+        value.add( Long.MIN_VALUE );
+        return value;
+    }
+
+    private Collection<Float> floatCollection()
+    {
+        Collection<Float> value = new ArrayList<>();
+        value.add( -1f );
+        value.add( 1f );
+        value.add( 1f );
+        value.add( 0f );
+        value.add( Float.MAX_VALUE );
+        value.add( Float.MIN_VALUE );
+        value.add( null );
+        value.add( 0.123456f );
+        value.add( -0.232321f );
+        return value;
+    }
+
+    private Collection<Double> doubleCollection()
+    {
+        Collection<Double> value = new ArrayList<>();
+        value.add( -1.0 );
+        value.add( 1.0 );
+        value.add( 0.0 );
+        value.add( Double.MAX_VALUE );
+        value.add( null );
+        value.add( Double.MIN_VALUE );
+        value.add( 0.123456 );
+        value.add( -0.232321 );
+        return value;
+    }
+
+    private Collection<BigInteger> bigIntegerCollection()
+    {
+        Collection<BigInteger> value = new ArrayList<>();
+        value.add( new BigInteger( "-1" ) );
+        value.add( BigInteger.ZERO );
+        value.add( BigInteger.ONE );
+        value.add( null );
+        value.add( BigInteger.TEN );
+        value.add( new BigInteger( "-1827368263823729372397239829332" ) );
+        value.add( new BigInteger( "2398723982982379827373972398723" ) );
+        return value;
+    }
+
+    private Collection<BigDecimal> bigDecimalCollection()
+    {
+        Collection<BigDecimal> value = new ArrayList<>();
+        value.add( new BigDecimal( "1.2" ) );
+        value.add( new BigDecimal( "3.4" ) );
+        value.add( null );
+        value.add( new BigDecimal( "5.6" ) );
+        return value;
+    }
+
+    private Map<String, Byte> stringByteMap()
+    {
+        Map<String, Byte> value = new LinkedHashMap<>();
+        value.put( "a", (byte) 9 );
+        value.put( "b", null );
+        value.put( "c", (byte) -12 );
+        return value;
+    }
+
+    private Map<String, List<String>> stringMultiMap()
+    {
+        Map<String, List<String>> value = new LinkedHashMap<>();
+        List<String> list = new ArrayList<>();
+        list.add( "foo" );
+        list.add( "bar" );
+        list.add( null );
+        list.add( "cathedral" );
+        list.add( "bazar" );
+        value.put( "alpha", list );
+        value.put( "beta", null );
+        value.put( "gamma", Collections.emptyList() );
+        return value;
+    }
+
+    private List<Map<String, String>> stringListOfMaps()
+    {
+        List<Map<String, String>> value = new ArrayList<>();
+        Map<String, String> map = new LinkedHashMap<>();
+        map.put( "foo", "bar" );
+        map.put( "cathedral", "bazar" );
+        map.put( "yield", null );
+        map.put( "42", "23" );
+        value.add( map );
+        value.add( null );
+        value.add( Collections.emptyMap() );
+        return value;
+    }
+
+    private List<SomeValue> valueCompositesList()
+    {
+        List<SomeValue> list = new ArrayList<>();
+        list.add( newSomeValue( "", "bazar" ) );
+        list.add( null );
+        list.add( newSomeValue( "bar", null ) );
+        return list;
+    }
+
+    public interface SomeValue
+    {
+        Property<String> foo();
+
+        @Optional
+        Property<String> cathedral();
+    }
+
+    private SomeValue newSomeValue( String foo, String cathedral )
+    {
+        ValueBuilder<SomeValue> builder = module.instance().newValueBuilder( SomeValue.class );
+        SomeValue value = builder.prototype();
+        value.foo().set( foo );
+        if( cathedral != null )
+        {
+            value.cathedral().set( cathedral );
+        }
+        return builder.newInstance();
+    }
+
+    private static class AdHocIterable<T> implements Iterable<T>
+    {
+        private final Iterable<T> delegate;
+
+        private AdHocIterable( Iterable<T> delegate )
+        {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public Iterator<T> iterator()
+        {
+            return delegate.iterator();
+        }
+    }
+
+    private enum SomeEnum
+    {
+        FOO,
+        BAR,
+        BAZAR,
+        CATHEDRAL
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractDateFormatSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractDateFormatSerializationTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractDateFormatSerializationTest.java
new file mode 100644
index 0000000..27b5289
--- /dev/null
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractDateFormatSerializationTest.java
@@ -0,0 +1,142 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.test.serialization;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.List;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.serialization.Serialization;
+import org.apache.polygene.api.type.CollectionType;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Assert that a serialization support various date formats.
+ */
+@SuppressWarnings( "ProtectedField" )
+public class AbstractDateFormatSerializationTest
+    extends AbstractPolygeneTest
+{
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+    }
+
+    @Service
+    protected Serialization stateSerialization;
+
+    @Test
+    public void givenLocalDateTimeFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.LOCAL_DATE_TIME );
+        List<LocalDateTime> value = stateSerialization.deserialize( module, collectionType,
+                                                                    "[\"2009-08-12T14:54:27\"]" );
+        LocalDateTime expected = LocalDateTime.of( 2009, 8, 12, 14, 54, 27 );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenLocalDateFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.LOCAL_DATE );
+        List<LocalDate> value = stateSerialization.deserialize( module, collectionType, "[\"2009-08-12\"]" );
+        LocalDate expected = LocalDate.of( 2009, 8, 12 );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenLocalTimeFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.LOCAL_TIME );
+        List<LocalTime> value = stateSerialization.deserialize( module, collectionType, "[\"14:54:27\"]" );
+        LocalTime expected = LocalTime.of( 14, 54, 27 );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenOffsetDateTimeFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.OFFSET_DATE_TIME );
+        List<OffsetDateTime> value = stateSerialization.deserialize( module, collectionType,
+                                                                     "[\"2009-08-12T14:54:27.895+08:00\"]" );
+        OffsetDateTime expected = OffsetDateTime.of( 2009, 8, 12, 14, 54, 27, 895000000, ZoneOffset.ofHours( 8 ) );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenZonedDateTimeFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.ZONED_DATE_TIME );
+        List<ZonedDateTime> value = stateSerialization.deserialize( module, collectionType,
+                                                                    "[\"2009-08-12T14:54:27.895+02:00[CET]\"]" );
+        ZonedDateTime expected = ZonedDateTime.of( 2009, 8, 12, 14, 54, 27, 895000000, ZoneId.of( "CET" ) );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenInstantFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.INSTANT );
+        List<Instant> value = stateSerialization.deserialize( module, collectionType,
+                                                              "[\"2016-06-11T08:47:12.620Z\"]" );
+        Instant expected = Instant.parse( "2016-06-11T08:47:12.620Z" );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenDurationFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.DURATION );
+        List<Duration> value = stateSerialization.deserialize( module, collectionType, "[\"PT3.5S\"]" );
+        Duration expected = Duration.ofMillis( 3500 );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+
+    @Test
+    public void givenPeriodFormatWhenConvertingFromSerializedStateExpectValidDate()
+        throws Exception
+    {
+        CollectionType collectionType = CollectionType.listOf( ValueType.PERIOD );
+        List<Period> value = stateSerialization.deserialize( module, collectionType, "[\"P3Y5M13D\"]" );
+        Period expected = Period.of( 3, 5, 13 );
+        assertThat( value.get( 0 ), equalTo( expected ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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
new file mode 100644
index 0000000..7e72ff1
--- /dev/null
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractPlainValueSerializationTest.java
@@ -0,0 +1,259 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.test.serialization;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.serialization.Serialization;
+import org.apache.polygene.api.type.EnumType;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Assert that ValueSerialization behaviour on plain values is correct.
+ */
+public abstract class AbstractPlainValueSerializationTest
+    extends AbstractPolygeneTest
+{
+    @Service
+    protected Serialization stateSerialization;
+
+    @Override
+    public void assemble( ModuleAssembly module )
+    {
+    }
+
+    @Test
+    public void givenEmptyStateStringWhenDeserializingExpectSuccesses()
+    {
+        assertThat( stateSerialization.deserialize( module, ValueType.of( Integer.class ), "" ), is( 0 ) );
+        assertThat( stateSerialization.deserialize( module, ValueType.of( String.class ), "" ), equalTo( "" ) );
+    }
+
+    @Test
+    public void givenNullValueWhenSerializingAndDeserializingExpectNull()
+    {
+        String output = stateSerialization.serialize( null );
+        System.out.println( output );
+        assertThat( stateSerialization.deserialize( module, ValueType.of( Integer.class ), output ), nullValue() );
+        assertThat( stateSerialization.deserialize( module, ValueType.of( String.class ), output ), nullValue() );
+        assertThat( stateSerialization.deserialize( module, ValueType.of( SomeEnum.class ), output ), nullValue() );
+    }
+
+    @Test
+    public void givenEnumValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String output = stateSerialization.serialize( SomeEnum.B�R );
+        System.out.println( output );
+        SomeEnum value = stateSerialization.deserialize( module, EnumType.of( SomeEnum.class ), output );
+        assertThat( value, is( SomeEnum.B�R ) );
+    }
+
+    @Test
+    public void givenCharacterValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( '\u222b' );
+        System.out.println(serialized);
+        assertThat( "Serialized", serialized, equalTo( "\u222b" ) );
+
+        Character deserialized = stateSerialization.deserialize( module, Character.class, serialized );
+        assertThat( "Deserialized", deserialized, equalTo( '\u222b' ) );
+
+        deserialized = stateSerialization.deserialize( module, char.class, serialized );
+        assertThat( "Deserialized", deserialized, equalTo( '\u222b' ) );
+    }
+
+    @Test
+    public void givenEmptyStringValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( "" );
+        assertThat( "Serialized", serialized, equalTo( "" ) );
+
+        String deserialized = stateSerialization.deserialize( module, String.class, serialized );
+        assertThat( "Deserialized", deserialized, equalTo( "" ) );
+    }
+
+    @Test
+    public void givenStringValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( "�\u222b" );
+        assertThat( serialized, equalTo( "�\u222b" ) );
+
+        String deserialized = stateSerialization.deserialize( module, String.class, serialized );
+        assertThat( deserialized, equalTo( "�\u222b" ) );
+    }
+
+    @Test
+    public void givenBooleanValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( true );
+        assertThat( serialized, equalTo( "true" ) );
+
+        Boolean deserialized = stateSerialization.deserialize( module, Boolean.class, serialized );
+        assertThat( deserialized, equalTo( Boolean.TRUE ) );
+    }
+
+    @Test
+    public void givenIntegerValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( 42 );
+        assertThat( serialized, equalTo( "42" ) );
+        Integer deserialized = stateSerialization.deserialize( module, Integer.class, serialized );
+        assertThat( deserialized, equalTo( 42 ) );
+    }
+
+    @Test
+    public void givenLongValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( 42L );
+        assertThat( serialized, equalTo( "42" ) );
+
+        Long deserialized = stateSerialization.deserialize( module, Long.class, serialized );
+        assertThat( deserialized, equalTo( 42L ) );
+    }
+
+    @Test
+    public void givenShortValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( (short) 42 );
+        assertThat( serialized, equalTo( "42" ) );
+
+        Short deserialized = stateSerialization.deserialize( module, Short.class, serialized );
+        assertThat( deserialized, equalTo( (short) 42 ) );
+    }
+
+    @Test
+    public void givenByteValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( (byte) 42 );
+        assertThat( serialized, equalTo( "42" ) );
+        Byte deserialized = stateSerialization.deserialize( module, Byte.class, serialized );
+        assertThat( deserialized, equalTo( (byte) 42 ) );
+    }
+
+    @Test
+    public void givenFloatValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( 42F );
+        assertThat( serialized, equalTo( "42.0" ) );
+
+        Float deserialized = stateSerialization.deserialize( module, Float.class, serialized );
+        assertThat( deserialized, equalTo( 42F ) );
+    }
+
+    @Test
+    public void givenDoubleValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( 42D );
+        assertThat( serialized, equalTo( "42.0" ) );
+
+        Double deserialized = stateSerialization.deserialize( module, Double.class, serialized );
+        assertThat( deserialized, equalTo( 42D ) );
+    }
+
+    @Test
+    public void givenBigIntegerValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        BigInteger bigInteger = new BigInteger( "42424242424242424242424242" );
+        assertThat( bigInteger, not( equalTo( BigInteger.valueOf( bigInteger.longValue() ) ) ) );
+
+        String serialized = stateSerialization.serialize( bigInteger );
+        assertThat( serialized, equalTo( "42424242424242424242424242" ) );
+
+        BigInteger deserialized = stateSerialization.deserialize( module, BigInteger.class, serialized );
+        assertThat( deserialized, equalTo( bigInteger ) );
+    }
+
+    @Test
+    public void givenBigDecimalValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        BigDecimal bigDecimal = new BigDecimal( "42.2376931348623157e+309" );
+        assertThat( bigDecimal.doubleValue(), equalTo( Double.POSITIVE_INFINITY ) );
+
+        String serialized = stateSerialization.serialize( bigDecimal );
+        assertThat( serialized, equalTo( "4.22376931348623157E+310" ) );
+
+        BigDecimal deserialized = stateSerialization.deserialize( module, BigDecimal.class, serialized );
+        assertThat( deserialized, equalTo( bigDecimal ) );
+    }
+
+    @Test
+    public void givenDateTimeValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize(
+            OffsetDateTime.of( 2020, 3, 4, 13, 24, 35, 123000000, ZoneOffset.ofHours( 1 ) ) );
+        assertThat( serialized, equalTo( "2020-03-04T13:24:35.123+01:00" ) );
+        ZonedDateTime deserialized = stateSerialization.deserialize( module, ZonedDateTime.class, serialized );
+        assertThat( deserialized,
+                    equalTo( ZonedDateTime.of( 2020, 3, 4, 13, 24, 35, 123000000, ZoneOffset.ofHours( 1 ) ) ) );
+    }
+
+    @Test
+    public void givenLocalDateTimeValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        // Serialized without TimeZone
+        String serialized = stateSerialization.serialize( LocalDateTime.of( 2020, 3, 4, 13, 23, 12 ) );
+        assertThat( serialized, equalTo( "2020-03-04T13:23:12" ) );
+
+        LocalDateTime deserialized = stateSerialization.deserialize( module, LocalDateTime.class, serialized );
+        assertThat( deserialized, equalTo( LocalDateTime.of( 2020, 3, 4, 13, 23, 12 ) ) );
+    }
+
+    @Test
+    public void givenLocalDateValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( LocalDate.of( 2020, 3, 4 ) );
+        assertThat( serialized, equalTo( "2020-03-04" ) );
+
+        LocalDate deserialized = stateSerialization.deserialize( module, LocalDate.class, serialized );
+        assertThat( deserialized, equalTo( LocalDate.of( 2020, 3, 4 ) ) );
+    }
+
+    @Test
+    public void givenEntityReferenceValueWhenSerializingAndDeserializingExpectEquals()
+    {
+        String serialized = stateSerialization.serialize( EntityReference.parseEntityReference( "ABCD-1234" ) );
+        assertThat( serialized, equalTo( "ABCD-1234" ) );
+
+        EntityReference deserialized = stateSerialization.deserialize( module, EntityReference.class, serialized );
+        assertThat( deserialized, equalTo( EntityReference.parseEntityReference( "ABCD-1234" ) ) );
+    }
+
+    private enum SomeEnum
+    {
+        B�R,
+        BAZAR
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/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
new file mode 100644
index 0000000..121fe21
--- /dev/null
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
@@ -0,0 +1,521 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+package org.apache.polygene.test.serialization;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.polygene.api.association.Association;
+import org.apache.polygene.api.association.ManyAssociation;
+import org.apache.polygene.api.association.NamedAssociation;
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.common.UseDefaults;
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.entity.EntityBuilder;
+import org.apache.polygene.api.entity.EntityComposite;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
+import org.apache.polygene.api.injection.scope.Service;
+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.Serialization;
+import org.apache.polygene.api.structure.Module;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.value.ValueBuilder;
+import org.apache.polygene.api.value.ValueComposite;
+import org.apache.polygene.bootstrap.AssemblyException;
+import org.apache.polygene.bootstrap.ModuleAssembly;
+import org.apache.polygene.test.AbstractPolygeneTest;
+import org.apache.polygene.test.EntityTestAssembler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+import static org.apache.polygene.api.usecase.UsecaseBuilder.newUsecase;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Assert that ValueSerialization behaviour on ValueComposites is correct.
+ */
+// TODO Assert Arrays behaviour!
+// TODO Assert Generics behaviour!
+public abstract class AbstractValueCompositeSerializationTest
+    extends AbstractPolygeneTest
+{
+    @Rule
+    public TestName testName = new TestName();
+
+    @Before
+    public void before()
+    {
+        System.out.println( "# BEGIN " + testName.getMethodName() );
+    }
+
+    @After
+    public void after()
+    {
+        System.out.println( "# END " + testName.getMethodName() );
+    }
+
+    @Structure
+    protected Module moduleInstance;
+
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.values( Some.class, AnotherValue.class, FooValue.class, CustomFooValue.class,
+                       SpecificCollection.class /*, SpecificValue.class, GenericValue.class */ );
+
+        new EntityTestAssembler().visibleIn( Visibility.layer ).assemble( module.layer().module( "persistence" ) );
+        module.entities( Some.class, BarEntity.class );
+    }
+
+    @Service
+    protected Serialization serialization;
+
+    @Test
+    public void givenValueCompositeWhenSerializingAndDeserializingExpectEquals()
+        throws Exception
+    {
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork() )
+        {
+            Some some = buildSomeValue( 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 ) );
+        }
+    }
+
+    @Test
+    @Ignore( "JSONEntityState cannot handle polymorphic deserialization" )
+    // TODO Entity == Identity + Value
+    // JSONEntityState does not allow for polymorphic serialization
+    public void valueAndEntityTypeEquality()
+    {
+        Identity identity = StringIdentity.fromString( "42" );
+        Some createdValue, loadedValue;
+
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( "create" ) ) )
+        {
+            Some entity = buildSomeEntity( moduleInstance, uow, identity );
+            createdValue = uow.toValue( Some.class, entity );
+            System.out.println( "Created Entity\n\t" + entity + "\nCreated Value\n\t" + createdValue );
+            uow.complete();
+        }
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( "load" ) ) )
+        {
+            Some entity = uow.get( Some.class, identity );
+            loadedValue = uow.toValue( Some.class, entity );
+            System.out.println( "Loaded Entity\n\t" + entity + "\nLoaded Value\n\t" + loadedValue );
+        }
+
+        assertThat( "Create/Read equality",
+                    createdValue, equalTo( loadedValue ) );
+
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( "remove" ) ) )
+        {
+            uow.remove( uow.get( Some.class, identity ) );
+            uow.complete();
+        }
+
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( "create from value" ) ) )
+        {
+            Some entity = uow.toEntity( Some.class, loadedValue );
+            createdValue = uow.toValue( Some.class, entity );
+            System.out.println( "Created Entity from Value\n\t" + entity + "\nCreated Value\n\t" + createdValue );
+            uow.complete();
+        }
+        try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( newUsecase( "read again" ) ) )
+        {
+            Some entity = uow.get( Some.class, identity );
+            loadedValue = uow.toValue( Some.class, entity );
+            System.out.println( "Loaded Entity\n\t" + entity + "\nLoaded Value\n\t" + loadedValue );
+        }
+
+        assertThat( "Create from Value/Read equality",
+                    createdValue, equalTo( loadedValue ) );
+    }
+
+    /**
+     * @return a Some ValueComposite whose state is populated with test data.
+     */
+    protected static Some buildSomeValue( Module module, UnitOfWork uow, String identity )
+    {
+        ValueBuilder<Some> builder = module.newValueBuilder( Some.class );
+        Some proto = builder.prototype();
+        proto.identity().set( StringIdentity.fromString( identity ) );
+        setSomeValueState( module, uow, proto );
+        return builder.newInstance();
+    }
+
+    /**
+     * @return a Some EntityComposite whose state is populated with test data.
+     */
+    protected static Some buildSomeEntity( Module module, UnitOfWork uow, Identity identity )
+    {
+        EntityBuilder<Some> builder = uow.newEntityBuilder( Some.class, identity );
+        setSomeValueState( module, uow, builder.instance() );
+        return builder.newInstance();
+    }
+
+    private static void setSomeValueState( Module module, UnitOfWork uow, Some some )
+    {
+        some.anotherList().get().add( module.newValue( AnotherValue.class ) );
+
+        ValueBuilder<SpecificCollection> specificColBuilder = module.newValueBuilder( SpecificCollection.class );
+        SpecificCollection specificColProto = specificColBuilder.prototype();
+        List<String> genericList = new ArrayList<>( 2 );
+        genericList.add( "Some" );
+        genericList.add( "String" );
+        specificColProto.genericList().set( genericList );
+        some.specificCollection().set( specificColBuilder.newInstance() );
+
+        AnotherValue anotherValue1 = createAnotherValue( module, "Foo", "Bar" );
+        AnotherValue anotherValue2 = createAnotherValue( module, "Habba", "ZoutZout" );
+        AnotherValue anotherValue3 = createAnotherValue( module, "Niclas", "Hedhman" );
+
+        some.string().set( "Foo\"Bar\"\nTest\f\t\b\r" );
+        some.string2().set( "/Foo/bar" );
+        some.number().set( 43L );
+        some.localTime().set( LocalTime.now() );
+        some.dateTime().set( OffsetDateTime.of( 2020, 3, 4, 13, 24, 35, 0, ZoneOffset.ofHours( 1 ) ) );
+        some.localDate().set( LocalDate.now() );
+        some.localDateTime().set( LocalDateTime.now() );
+        some.entityReference().set( EntityReference.parseEntityReference( "12345" ) );
+        some.stringIntMap().get().put( "foo", 42 );
+
+        // Can't put more than one entry in Map because this test rely on the fact that the underlying implementations
+        // maintain a certain order but it's not the case on some JVMs. On OpenJDK 8 they are reversed for example.
+        // This should not be enforced tough as both the Map API and the JSON specification state that name-value pairs
+        // are unordered.
+        // As a consequence this test should be enhanced to be Map order independant.
+        //
+        // proto.stringIntMap().get().put( "bar", 67 );
+
+        some.stringValueMap().get().put( "foo", anotherValue1 );
+        some.another().set( anotherValue1 );
+        // some.arrayOfValues().set( new AnotherValue[] { anotherValue1, anotherValue2, anotherValue3 } );
+        some.serializable().set( new SerializableObject() );
+        some.foo().set( module.newValue( FooValue.class ) );
+        some.fooValue().set( module.newValue( FooValue.class ) );
+        some.customFoo().set( module.newValue( CustomFooValue.class ) );
+        some.customFooValue().set( module.newValue( CustomFooValue.class ) );
+
+        // Arrays
+        // TODO FIXME Disabled as ValueComposite equality fails here
+        //proto.primitiveByteArray().set( new byte[]
+        //    {
+        //        9, -12, 42, -12, 127, 23, -128, 73
+        //    } );
+        //proto.byteArray().set( new Byte[]
+        //    {
+        //        9, null, -12, 23, -12, 127, -128, 73
+        //    } );
+
+        // NestedEntities
+        some.barAssociation().set( buildBarEntity( uow, "bazar in barAssociation" ) );
+        some.barEntityAssociation().set( buildBarEntity( uow, "bazar in barEntityAssociation" ) );
+        some.barManyAssociation().add( buildBarEntity( uow, "bazar ONE in barManyAssociation" ) );
+        some.barManyAssociation().add( buildBarEntity( uow, "bazar TWO in barManyAssociation" ) );
+        some.barEntityManyAssociation().add( buildBarEntity( uow, "bazar ONE in barEntityManyAssociation" ) );
+        some.barEntityManyAssociation().add( buildBarEntity( uow, "bazar TWO in barEntityManyAssociation" ) );
+        some.barNamedAssociation().put( "bazar", buildBarEntity( uow, "bazar in barNamedAssociation" ) );
+        some.barNamedAssociation().put( "cathedral", buildBarEntity( uow, "cathedral in barNamedAssociation" ) );
+        some.barEntityNamedAssociation().put( "bazar",
+                                              buildBarEntity( uow, "bazar in barEntityNamedAssociation" ) );
+        some.barEntityNamedAssociation().put( "cathedral",
+                                              buildBarEntity( uow, "cathedral in barEntityNamedAssociation" ) );
+    }
+
+    private static AnotherValue createAnotherValue( Module module, String val1, String val2 )
+    {
+        ValueBuilder<AnotherValue> valueBuilder = module.newValueBuilder( AnotherValue.class );
+        valueBuilder.prototype().val1().set( val1 );
+        valueBuilder.prototypeFor( AnotherValueInternalState.class ).val2().set( val2 );
+        return valueBuilder.newInstance();
+    }
+
+    private static BarEntity buildBarEntity( UnitOfWork uow, String cathedral )
+    {
+        EntityBuilder<BarEntity> barBuilder = uow.newEntityBuilder( BarEntity.class );
+        barBuilder.instance().cathedral().set( cathedral );
+        return barBuilder.newInstance();
+    }
+
+    public enum TestEnum
+    {
+        somevalue,
+        anothervalue
+    }
+
+    public interface Some extends HasIdentity
+    {
+        Property<String> string();
+
+        Property<String> string2();
+
+        @Optional
+        Property<String> nullString();
+
+        @UseDefaults
+        Property<String> emptyString();
+
+        @UseDefaults
+        Property<Long> number();
+
+        Property<LocalTime> localTime();
+
+        Property<OffsetDateTime> dateTime();
+
+        Property<LocalDate> localDate();
+
+        Property<LocalDateTime> localDateTime();
+
+        Property<EntityReference> entityReference();
+
+        @UseDefaults
+        Property<List<String>> stringList();
+
+        @UseDefaults
+        Property<Map<String, Integer>> stringIntMap();
+
+        @UseDefaults
+        Property<Map<String, AnotherValue>> stringValueMap();
+
+        Property<AnotherValue> another();
+
+        // Property<AnotherValue[]> arrayOfValues();
+
+        @Optional
+        Property<AnotherValue> anotherNull();
+
+        @UseDefaults
+        Property<List<AnotherValue>> anotherList();
+
+        @Optional
+        Property<List<AnotherValue>> anotherListNull();
+
+        @UseDefaults
+        Property<List<AnotherValue>> anotherListEmpty();
+
+        @UseDefaults
+        Property<TestEnum> testEnum();
+
+        // TODO FIXME Disabled as ValueComposite equality fails here
+        //Property<byte[]> primitiveByteArray();
+        //
+        //@Optional
+        //Property<byte[]> primitiveByteArrayNull();
+        //
+        //Property<Byte[]> byteArray();
+        //
+        //@Optional
+        //Property<Byte[]> byteArrayNull();
+
+        Property<Object> serializable();
+
+        Property<Foo> foo();
+
+        Property<FooValue> fooValue();
+
+        Property<Foo> customFoo();
+
+        Property<FooValue> customFooValue();
+
+        Property<SpecificCollection> specificCollection();
+
+        /* Too complicated to do generics here for now
+         Property<SpecificValue> specificValue();
+         */
+        @Optional
+        Association<Bar> barAssociationOptional();
+
+        Association<Bar> barAssociation();
+
+        Association<BarEntity> barEntityAssociation();
+
+        ManyAssociation<Bar> barManyAssociationEmpty();
+
+        ManyAssociation<Bar> barManyAssociation();
+
+        ManyAssociation<BarEntity> barEntityManyAssociation();
+
+        NamedAssociation<Bar> barNamedAssociationEmpty();
+
+        NamedAssociation<Bar> barNamedAssociation();
+
+        NamedAssociation<BarEntity> barEntityNamedAssociation();
+    }
+
+    public interface SpecificCollection
+        extends GenericCollection<String>
+    {
+    }
+
+    public interface GenericCollection<TYPE>
+        extends ValueComposite
+    {
+        @UseDefaults
+        Property<List<TYPE>> genericList();
+    }
+
+    public interface SpecificValue
+        extends GenericValue<String>
+    {
+    }
+
+    public interface GenericValue<TYPE>
+        extends ValueComposite
+    {
+        @Optional
+        Property<TYPE> item();
+    }
+
+    @Mixins( AnotherValueMixin.class )
+    public interface AnotherValue
+        extends ValueComposite
+    {
+        @UseDefaults
+        Property<String> val1();
+
+        String internalVal();
+    }
+
+    public interface AnotherValueInternalState
+    {
+        @UseDefaults
+        Property<String> val2();
+    }
+
+    public static abstract class AnotherValueMixin
+        implements AnotherValue
+    {
+        @This
+        private AnotherValueInternalState internalState;
+
+        @Override
+        public String internalVal()
+        {
+            return internalState.val2().get();
+        }
+    }
+
+    public interface Foo
+    {
+        @UseDefaults
+        Property<String> bar();
+    }
+
+    public interface FooValue
+        extends Foo, ValueComposite
+    {
+    }
+
+    public interface CustomFooValue
+        extends FooValue
+    {
+        @UseDefaults
+        Property<String> custom();
+    }
+
+    public interface Bar
+    {
+        @UseDefaults
+        Property<String> cathedral();
+    }
+
+    public interface BarEntity
+        extends Bar, EntityComposite
+    {
+    }
+
+    public static class SerializableObject
+        implements Serializable
+    {
+        private static final long serialVersionUID = 1L;
+        private final String foo = "Foo";
+        private final int val = 35;
+
+        @Override
+        public boolean equals( Object o )
+        {
+            if( this == o )
+            {
+                return true;
+            }
+            if( o == null || getClass() != o.getClass() )
+            {
+                return false;
+            }
+            SerializableObject that = (SerializableObject) o;
+            return val == that.val && foo.equals( that.foo );
+        }
+
+        @Override
+        public int hashCode()
+        {
+            int result = foo.hashCode();
+            result = 31 * result + val;
+            return result;
+        }
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/serialization/package.html
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/package.html b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/package.html
new file mode 100644
index 0000000..7a03a27
--- /dev/null
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/package.html
@@ -0,0 +1,24 @@
+<!--
+  ~  Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  ~
+  -->
+<html>
+    <body>
+        <h2>Serialization SPI Test Support.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/c9dd7229/core/testsupport/src/main/java/org/apache/polygene/test/util/JSONAssert.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/util/JSONAssert.java b/core/testsupport/src/main/java/org/apache/polygene/test/util/JSONAssert.java
deleted file mode 100644
index 7652596..0000000
--- a/core/testsupport/src/main/java/org/apache/polygene/test/util/JSONAssert.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *
- */
-package org.apache.polygene.test.util;
-
-import java.util.Iterator;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.junit.Assert;
-
-/**
- * A set of assertion methods useful for tests using org.json.
- */
-public class JSONAssert
-    extends Assert
-{
-
-    /**
-     * Assert that two JSONObjects are equals without enforcing field order.
-     *
-     * @param o1 First JSON object
-     * @param o2 Second JSON object
-     * @throws JSONException on json parsing error
-     */
-    public static void jsonObjectsEquals( JSONObject o1, JSONObject o2 )
-        throws JSONException
-    {
-        if( o1 != o2 )
-        {
-            if( o1.length() != o2.length() )
-            {
-                fail( "JSONObjects length differ: " + o1.length() + " / " + o2.length() );
-            }
-            @SuppressWarnings( "unchecked" )
-            Iterator<String> o1Keys = o1.keys();
-            while( o1Keys.hasNext() )
-            {
-                String key = o1Keys.next();
-                Object o1Value = o1.get( key );
-                Object o2Value = o2.get( key );
-                if( !jsonValueEquals( o1Value, o2Value ) )
-                {
-                    fail( "JSONObject '" + key + "' values differ: " + o1Value + " / " + o2Value );
-                }
-            }
-        }
-    }
-
-    /**
-     * Assert that two JSONArrays are equals.
-     *
-     * @param a1 First JSON array
-     * @param a2 Second JSON array
-     * @throws JSONException on json parsing error
-     */
-    public static void jsonArraysEquals( JSONArray a1, JSONArray a2 )
-        throws JSONException
-    {
-        if( a1 != a2 )
-        {
-            if( a1.length() != a2.length() )
-            {
-                fail( "JSONArrays length differ: " + a1.length() + " / " + a2.length() );
-            }
-            for( int idx = 0; idx < a1.length(); idx++ )
-            {
-                Object a1Value = a1.get( idx );
-                Object a2Value = a2.get( idx );
-                if( !jsonValueEquals( a1Value, a2Value ) )
-                {
-                    fail( "JSONArray '" + idx + "' values differ: " + a1Value + " / " + a2Value );
-                }
-            }
-        }
-    }
-
-    private static boolean jsonValueEquals( Object o1Value, Object o2Value )
-        throws JSONException
-    {
-        if( o1Value instanceof JSONObject )
-        {
-
-            if( !( o2Value instanceof JSONObject ) )
-            {
-                return false;
-            }
-            jsonObjectsEquals( (JSONObject) o1Value, (JSONObject) o2Value );
-
-        }
-        else if( o1Value instanceof JSONArray )
-        {
-
-            if( !( o2Value instanceof JSONArray ) )
-            {
-                return false;
-            }
-            jsonArraysEquals( (JSONArray) o1Value, (JSONArray) o2Value );
-
-        }
-        else if( !o1Value.equals( o2Value ) )
-        {
-
-            return false;
-
-        }
-        return true;
-    }
-
-    private JSONAssert()
-    {
-    }
-
-}