http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/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
new file mode 100644
index 0000000..17982f3
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractDeserializer.java
@@ -0,0 +1,155 @@
+/*
+ *  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.serialization;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+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.entity.EntityReference;
+import org.apache.polygene.api.serialization.Deserializer;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.CollectionType;
+import org.apache.polygene.api.type.MapType;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.spi.module.ModuleSpi;
+
+public abstract class AbstractDeserializer implements Deserializer
+{
+    protected static final ValueType ENTITY_REF_LIST_VALUE_TYPE = 
CollectionType.listOf( EntityReference.class );
+    protected static final ValueType ENTITY_REF_MAP_VALUE_TYPE = MapType.of( 
String.class, EntityReference.class );
+
+    @Override
+    public <T> T deserialize( ModuleDescriptor module, ValueType valueType, 
String state )
+    {
+        return deserialize( module, valueType, new StringReader( state ) );
+    }
+
+    @Override
+    public <T> Function<String, T> deserializeFunction( ModuleDescriptor 
module, ValueType valueType )
+    {
+        return state -> deserialize( module, valueType, new StringReader( 
state ) );
+    }
+
+    @Override
+    public <T> Stream<T> deserializeEach( ModuleDescriptor module, ValueType 
valueType, Iterable<String> states )
+    {
+        return StreamSupport.stream( states.spliterator(), false )
+                            .map( state -> deserialize( module, valueType, new 
StringReader( state ) ) );
+    }
+
+    @Override
+    public <T> Stream<T> deserializeEach( ModuleDescriptor module, ValueType 
valueType, String... states )
+    {
+        return Stream.of( states ).map( state -> deserialize( module, 
valueType, new StringReader( state ) ) );
+    }
+
+    @Override
+    public <T> T fromBytes( ModuleDescriptor module, ValueType valueType, 
byte[] bytes )
+    {
+        return deserialize( module, valueType, new ByteArrayInputStream( bytes 
) );
+    }
+
+    @Override
+    public <T> Function<byte[], T> fromBytesFunction( ModuleDescriptor module, 
ValueType valueType )
+    {
+        return bytes -> deserialize( module, valueType, new 
ByteArrayInputStream( bytes ) );
+    }
+
+    @Override
+    public <T> Stream<T> fromBytesEach( ModuleDescriptor module, ValueType 
valueType, Iterable<byte[]> states )
+    {
+        return StreamSupport.stream( states.spliterator(), false )
+                            .map( bytes -> deserialize( module, valueType, new 
ByteArrayInputStream( bytes ) ) );
+    }
+
+    @Override
+    public <T> Stream<T> fromBytesEach( ModuleDescriptor module, ValueType 
valueType, byte[]... states )
+    {
+        return Stream.of( states ).map( bytes -> deserialize( module, 
valueType, new ByteArrayInputStream( bytes ) ) );
+    }
+
+    @Override
+    public <T> T deserialize( ModuleDescriptor module, Class<T> type, 
InputStream state )
+    {
+        return deserialize( module, valueTypeOf( module, type ), state );
+    }
+
+    @Override
+    public <T> T deserialize( ModuleDescriptor module, Class<T> type, Reader 
state )
+    {
+        return deserialize( module, valueTypeOf( module, type ), state );
+    }
+
+    @Override
+    public <T> T deserialize( ModuleDescriptor module, Class<T> type, String 
state )
+    {
+        return deserialize( module, valueTypeOf( module, type ), state );
+    }
+
+    @Override
+    public <T> Function<String, T> deserializeFunction( ModuleDescriptor 
module, Class<T> type )
+    {
+        return deserializeFunction( module, valueTypeOf( module, type ) );
+    }
+
+    @Override
+    public <T> Stream<T> deserializeEach( ModuleDescriptor module, Class<T> 
type, Iterable<String> states )
+    {
+        return deserializeEach( module, valueTypeOf( module, type ), states );
+    }
+
+    @Override
+    public <T> Stream<T> deserializeEach( ModuleDescriptor module, Class<T> 
type, String... states )
+    {
+        return deserializeEach( module, valueTypeOf( module, type ), states );
+    }
+
+    @Override
+    public <T> T fromBytes( ModuleDescriptor module, Class<T> type, byte[] 
bytes )
+    {
+        return fromBytes( module, valueTypeOf( module, type ), bytes );
+    }
+
+    @Override
+    public <T> Function<byte[], T> fromBytesFunction( ModuleDescriptor module, 
Class<T> type )
+    {
+        return fromBytesFunction( module, valueTypeOf( module, type ) );
+    }
+
+    @Override
+    public <T> Stream<T> fromBytesEach( ModuleDescriptor module, Class<T> 
type, Iterable<byte[]> states )
+    {
+        return fromBytesEach( module, valueTypeOf( module, type ), states );
+    }
+
+    @Override
+    public <T> Stream<T> fromBytesEach( ModuleDescriptor module, Class<T> 
type, byte[]... states )
+    {
+        return fromBytesEach( module, valueTypeOf( module, type ), states );
+    }
+
+    private ValueType valueTypeOf( ModuleDescriptor module, Class<?> type )
+    {
+        // TODO Remove (ModuleSpi) cast
+        return ( (ModuleSpi) module.instance() 
).valueTypeFactory().valueTypeOf( module, type );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/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
new file mode 100644
index 0000000..b5f10ff
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractSerializer.java
@@ -0,0 +1,147 @@
+/*
+ *  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.serialization;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+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.Serializer;
+
+public abstract class AbstractSerializer implements Serializer
+{
+    @Override
+    public void serialize( Writer writer, @Optional Object object )
+    {
+        serialize( Options.DEFAULT, writer, object );
+    }
+
+    @Override
+    public void serialize( OutputStream output, @Optional Object object )
+    {
+        serialize( Options.DEFAULT, output, object );
+    }
+
+    @Override
+    public String serialize( Options options, @Optional Object object )
+    {
+        StringWriter writer = new StringWriter();
+        serialize( options, writer, object );
+        return writer.toString();
+    }
+
+    @Override
+    public String serialize( @Optional Object object )
+    {
+        return serialize( Options.DEFAULT, object );
+    }
+
+    @Override
+    public <T> Function<T, String> serializeFunction( Options options )
+    {
+        return object -> serialize( options, object );
+    }
+
+    @Override
+    public <T> Function<T, String> serializeFunction()
+    {
+        return object -> serialize( Options.DEFAULT, object );
+    }
+
+    @Override
+    public Stream<String> serializeEach( Options options, Iterable<Object> 
objects )
+    {
+        return StreamSupport.stream( objects.spliterator(), false )
+                            .map( object -> serialize( options, object ) );
+    }
+
+    @Override
+    public Stream<String> serializeEach( Iterable<Object> objects )
+    {
+        return StreamSupport.stream( objects.spliterator(), false )
+                            .map( object -> serialize( Options.DEFAULT, object 
) );
+    }
+
+    @Override
+    public Stream<String> serializeEach( Options options, Object... objects )
+    {
+        return Stream.of( objects ).map( object -> serialize( options, object 
) );
+    }
+
+    @Override
+    public Stream<String> serializeEach( Object... objects )
+    {
+        return Stream.of( objects ).map( object -> serialize( Options.DEFAULT, 
object ) );
+    }
+
+    @Override
+    public byte[] toBytes( Options options, @Optional Object object )
+    {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        serialize( options, output, object );
+        return output.toByteArray();
+    }
+
+    @Override
+    public byte[] toBytes( @Optional Object object )
+    {
+        return toBytes( Options.DEFAULT, object );
+    }
+
+    @Override
+    public <T> Function<T, byte[]> toBytesFunction( Options options )
+    {
+        return object -> toBytes( options, object );
+    }
+
+    @Override
+    public <T> Function<T, byte[]> toBytesFunction()
+    {
+        return object -> toBytes( Options.DEFAULT, object );
+    }
+
+    @Override
+    public Stream<byte[]> toBytesEach( Options options, Iterable<Object> 
objects )
+    {
+        return StreamSupport.stream( objects.spliterator(), false )
+                            .map( object -> toBytes( options, object ) );
+    }
+
+    @Override
+    public Stream<byte[]> toBytesEach( Iterable<Object> objects )
+    {
+        return StreamSupport.stream( objects.spliterator(), false )
+                            .map( object -> toBytes( Options.DEFAULT, object ) 
);
+    }
+
+    @Override
+    public Stream<byte[]> toBytesEach( Options options, Object... objects )
+    {
+        return Stream.of( objects ).map( object -> toBytes( options, object ) 
);
+    }
+
+    @Override
+    public Stream<byte[]> toBytesEach( Object... objects )
+    {
+        return Stream.of( objects ).map( object -> toBytes( Options.DEFAULT, 
object ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextDeserializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextDeserializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextDeserializer.java
new file mode 100644
index 0000000..0575489
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextDeserializer.java
@@ -0,0 +1,34 @@
+/*
+ *  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.serialization;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.ValueType;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+public abstract class AbstractTextDeserializer extends AbstractDeserializer
+{
+    @Override
+    public <T> T deserialize( ModuleDescriptor module, ValueType valueType, 
InputStream state )
+    {
+        return deserialize( module, valueType, new InputStreamReader( state, 
UTF_8 ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextSerializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextSerializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextSerializer.java
new file mode 100644
index 0000000..3d8bb16
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/AbstractTextSerializer.java
@@ -0,0 +1,48 @@
+/*
+ *  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.serialization;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.UncheckedIOException;
+import org.apache.polygene.api.common.Optional;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Base Text Serializer.
+ *
+ * Implementations work on Strings, this base serializer encode these strings 
in UTF-8 to produce bytes.
+ */
+public abstract class AbstractTextSerializer extends AbstractSerializer
+{
+    public void serialize( Options options, OutputStream output, @Optional 
Object object )
+    {
+        try
+        {
+            StringWriter writer = new StringWriter();
+            serialize( options, writer, object );
+            output.write( writer.toString().getBytes( UTF_8 ) );
+        }
+        catch( IOException ex )
+        {
+            throw new UncheckedIOException( ex );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/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
new file mode 100644
index 0000000..8bf3584
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonDeserializer.java
@@ -0,0 +1,162 @@
+/*
+ *  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.serialization;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UncheckedIOException;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;
+import org.apache.polygene.api.serialization.Deserializer;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.spi.module.ModuleSpi;
+
+import static java.util.stream.Collectors.joining;
+
+public interface JsonDeserializer extends Deserializer
+{
+    <T> T fromJson( ModuleDescriptor module, ValueType valueType, JsonValue 
state );
+
+    default <T> Function<JsonValue, T> fromJsonFunction( ModuleDescriptor 
module, ValueType valueType )
+    {
+        return state -> fromJson( module, valueType, state );
+    }
+
+    default <T> Stream<T> fromJsonEach( ModuleDescriptor module, ValueType 
valueType, Stream<JsonValue> states )
+    {
+        return states.map( fromJsonFunction( module, valueType ) );
+    }
+
+    default <T> Stream<T> fromJsonEach( ModuleDescriptor module, ValueType 
valueType, Iterable<JsonValue> states )
+    {
+        return fromJsonEach( module, valueType, StreamSupport.stream( 
states.spliterator(), false ) );
+    }
+
+    default <T> Stream<T> fromJsonEach( ModuleDescriptor module, ValueType 
valueType, JsonValue... states )
+    {
+        return fromJsonEach( module, valueType, Stream.of( states ) );
+    }
+
+    default <T> T fromJson( ModuleDescriptor module, Class<T> type, JsonValue 
state )
+    {
+        // TODO Remove (ModuleSpi) cast
+        ValueType valueType = ( (ModuleSpi) module.instance() 
).valueTypeFactory().valueTypeOf( module, type );
+        return fromJson( module, valueType, state );
+    }
+
+    default <T> Function<JsonValue, T> fromJson( ModuleDescriptor module, 
Class<T> type )
+    {
+        return state -> fromJson( module, type, state );
+    }
+
+    default <T> Stream<T> fromJsonEach( ModuleDescriptor module, Class<T> 
valueType, Stream<JsonValue> states )
+    {
+        return states.map( fromJson( module, valueType ) );
+    }
+
+    default <T> Stream<T> fromJsonEach( ModuleDescriptor module, Class<T> 
valueType, Iterable<JsonValue> states )
+    {
+        return fromJsonEach( module, valueType, StreamSupport.stream( 
states.spliterator(), false ) );
+    }
+
+    default <T> Stream<T> fromJsonEach( ModuleDescriptor module, Class<T> 
valueType, JsonValue... states )
+    {
+        return fromJsonEach( module, valueType, Stream.of( states ) );
+    }
+
+    @Override
+    default <T> T deserialize( ModuleDescriptor module, ValueType valueType, 
Reader state )
+    {
+        // JSR-353 Does not allow reading "out of structure" values
+        // See https://www.jcp.org/en/jsr/detail?id=353
+        // And commented JsonReader#readValue() method in the javax.json API
+        // BUT, it will be part of the JsonReader contract in the next version
+        // See https://www.jcp.org/en/jsr/detail?id=374
+        // Implementation by provider is optional though, so we'll always need 
a default implementation here.
+        // Fortunately, JsonParser has new methods allowing to read structures 
while parsing so it will be easy to do.
+        // In the meantime, a poor man's implementation will do.
+        // TODO Revisit values out of structure JSON deserialization when 
JSR-374 is out
+        String stateString;
+        try( BufferedReader buffer = new BufferedReader( state ) )
+        {
+            stateString = buffer.lines().collect( joining( "\n" ) );
+        }
+        catch( IOException ex )
+        {
+            throw new UncheckedIOException( ex );
+        }
+        // We want plain Strings, BigDecimals, BigIntegers to be deserialized 
even when unquoted
+        Function<String, T> plainValueFunction = string ->
+        {
+            String poorMans = "{\"value\":" + string + "}";
+            JsonObject poorMansJson = Json.createReader( new StringReader( 
poorMans ) ).readObject();
+            JsonValue value = poorMansJson.get( "value" );
+            return fromJson( module, valueType, value );
+        };
+        Function<String, T> outOfStructureFunction = string ->
+        {
+            // Is this an unquoted plain value?
+            try
+            {
+                return plainValueFunction.apply( '"' + string + '"' );
+            }
+            catch( JsonParsingException ex )
+            {
+                return plainValueFunction.apply( string );
+            }
+        };
+        try( JsonParser parser = Json.createParser( new StringReader( 
stateString ) ) )
+        {
+            if( parser.hasNext() )
+            {
+                JsonParser.Event e = parser.next();
+                if( e == JsonParser.Event.START_ARRAY || e == 
JsonParser.Event.START_OBJECT )
+                {
+                    // JSON Structure
+                    try( JsonReader reader = Json.createReader( new 
StringReader( stateString ) ) )
+                    {
+                        return fromJson( module, valueType, reader.read() );
+                    }
+                }
+                else
+                {
+                    // JSON Value out of structure
+                    return outOfStructureFunction.apply( stateString );
+                }
+            }
+        }
+        catch( JsonParsingException ex )
+        {
+            return outOfStructureFunction.apply( stateString );
+        }
+        // Empty state string?
+        JsonValue emptyJsonString = Json.createReader( new StringReader( 
"{\"empty\":\"\"}" ) )
+                                        .readObject().get( "empty" );
+        return fromJson( module, valueType, emptyJsonString );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerialization.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerialization.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerialization.java
new file mode 100644
index 0000000..a98e70f
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerialization.java
@@ -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.
+ */
+package org.apache.polygene.spi.serialization;
+
+import org.apache.polygene.api.serialization.Serialization;
+
+public interface JsonSerialization extends Serialization, JsonSerializer, 
JsonDeserializer
+{
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
new file mode 100644
index 0000000..b64f240
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/JsonSerializer.java
@@ -0,0 +1,106 @@
+/*
+ *  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.serialization;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.serialization.Serializer;
+
+public interface JsonSerializer extends Serializer
+{
+    <T> Function<T, JsonValue> toJsonFunction( Options options );
+
+    default <T> Function<T, JsonValue> toJsonFunction()
+    {
+        return object -> toJsonFunction( Options.DEFAULT ).apply( object );
+    }
+
+    default JsonValue toJson( Options options, @Optional Object object )
+    {
+        return toJsonFunction( options ).apply( object );
+    }
+
+    default JsonValue toJson( @Optional Object object )
+    {
+        return toJsonFunction( Options.DEFAULT ).apply( object );
+    }
+
+    default <T> Stream<JsonValue> toJsonEach( Options options, Stream<T> 
objects )
+    {
+        return objects.map( toJsonFunction( options ) );
+    }
+
+    default <T> Stream<JsonValue> toJsonEach( Options options, Iterable<T> 
objects )
+    {
+        return toJsonEach( options, StreamSupport.stream( 
objects.spliterator(), false ) );
+    }
+
+    default <T> Stream<JsonValue> toJsonEach( Options options, Object... 
objects )
+    {
+        return toJsonEach( options, Stream.of( objects ) );
+    }
+
+    default <T> Stream<JsonValue> toJsonEach( Stream<T> objects )
+    {
+        return objects.map( toJsonFunction( Options.DEFAULT ) );
+    }
+
+    default <T> Stream<JsonValue> toJsonEach( Iterable<T> objects )
+    {
+        return toJsonEach( Options.DEFAULT, StreamSupport.stream( 
objects.spliterator(), false ) );
+    }
+
+    default <T> Stream<JsonValue> toJsonEach( Object... objects )
+    {
+        return toJsonEach( Options.DEFAULT, Stream.of( objects ) );
+    }
+
+    default void serialize( Options options, Writer writer, @Optional Object 
object )
+    {
+        JsonValue jsonValue = toJson( options, object );
+        if( jsonValue == null )
+        {
+            return;
+        }
+        try
+        {
+            // TODO FIX ThIS SHIT of "out of structure" value (de)serialization
+            // We want plain Strings to be serialized without quotes which is 
non JSON compliant
+            // See https://java.net/jira/browse/JSON_PROCESSING_SPEC-65
+            if( jsonValue.getValueType() == JsonValue.ValueType.STRING )
+            {
+                writer.write( ( (JsonString) jsonValue ).getString() );
+            }
+            else
+            {
+                writer.write( jsonValue.toString() );
+            }
+        }
+        catch( IOException ex )
+        {
+            throw new UncheckedIOException( ex );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/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
new file mode 100644
index 0000000..c7ac42b
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlDeserializer.java
@@ -0,0 +1,107 @@
+/*
+ *  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.serialization;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+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.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.ValueDescriptor;
+import org.apache.polygene.spi.module.ModuleSpi;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public interface XmlDeserializer extends Deserializer
+{
+    <T> T fromXml( ModuleDescriptor module, ValueType valueType, Document 
state );
+
+    default <T> Function<Document, T> fromXmlFunction( ModuleDescriptor 
module, ValueType valueType )
+    {
+        return state -> fromXml( module, valueType, state );
+    }
+
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType 
valueType, Stream<Document> states )
+    {
+        return states.map( fromXmlFunction( module, valueType ) );
+    }
+
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType 
valueType, Iterable<Document> states )
+    {
+        return fromXmlEach( module, valueType, StreamSupport.stream( 
states.spliterator(), false ) );
+    }
+
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, ValueType 
valueType, Document... states )
+    {
+        return fromXmlEach( module, valueType, Stream.of( states ) );
+    }
+
+    default <T> T fromXml( ModuleDescriptor module, Class<T> type, Document 
state )
+    {
+        // TODO Remove (ModuleSpi) cast
+        ValueType valueType = ( (ModuleSpi) module.instance() 
).valueTypeFactory().valueTypeOf( module, type );
+        return fromXml( module, valueType, state );
+    }
+
+    default <T> Function<Document, T> fromXml( ModuleDescriptor module, 
Class<T> type )
+    {
+        return state -> fromXml( module, type, state );
+    }
+
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> 
valueType, Stream<Document> states )
+    {
+        return states.map( fromXml( module, valueType ) );
+    }
+
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> 
valueType, Iterable<Document> states )
+    {
+        return fromXmlEach( module, valueType, StreamSupport.stream( 
states.spliterator(), false ) );
+    }
+
+    default <T> Stream<T> fromXmlEach( ModuleDescriptor module, Class<T> 
valueType, Document... states )
+    {
+        return fromXmlEach( module, valueType, Stream.of( states ) );
+    }
+
+    @Override
+    default <T> T deserialize( ModuleDescriptor module, ValueType valueType, 
Reader state )
+    {
+        try
+        {
+            DocumentBuilder docBuilder = 
DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            Document doc = docBuilder.parse( new InputSource( state ) );
+            return fromXml( module, valueType, doc );
+        }
+        catch( SAXException | IOException | ParserConfigurationException ex )
+        {
+            throw new SerializationException( "Unable to read XML document", 
ex );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerialization.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerialization.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerialization.java
new file mode 100644
index 0000000..12fda54
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerialization.java
@@ -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.
+ */
+package org.apache.polygene.spi.serialization;
+
+import org.apache.polygene.api.serialization.Serialization;
+
+public interface XmlSerialization extends Serialization, XmlSerializer, 
XmlDeserializer
+{
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
new file mode 100644
index 0000000..e244d63
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/XmlSerializer.java
@@ -0,0 +1,118 @@
+/*
+ *  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.serialization;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.polygene.api.common.Optional;
+import org.apache.polygene.api.serialization.SerializationException;
+import org.apache.polygene.api.serialization.Serializer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * XML State Serializer.
+ */
+public interface XmlSerializer extends Serializer
+{
+    <T> Function<T, Document> toXmlFunction( Options options );
+
+    default <T> Function<T, Document> toXmlFunction()
+    {
+        return object -> toXmlFunction( Options.DEFAULT ).apply( object );
+    }
+
+    default Document toXml( Options options, @Optional Object object )
+    {
+        return toXmlFunction( options ).apply( object );
+    }
+
+    default Document toXml( @Optional Object object )
+    {
+        return toXmlFunction( Options.DEFAULT ).apply( object );
+    }
+
+    default <T> Stream<Document> toXmlEach( Options options, Stream<T> objects 
)
+    {
+        return objects.map( toXmlFunction( options ) );
+    }
+
+    default <T> Stream<Document> toXmlEach( Options options, Iterable<T> 
objects )
+    {
+        return toXmlEach( options, StreamSupport.stream( 
objects.spliterator(), false ) );
+    }
+
+    default <T> Stream<Document> toXmlEach( Options options, Object... objects 
)
+    {
+        return toXmlEach( options, Stream.of( objects ) );
+    }
+
+    default <T> Stream<Document> toXmlEach( Stream<T> objects )
+    {
+        return objects.map( toXmlFunction( Options.DEFAULT ) );
+    }
+
+    default <T> Stream<Document> toXmlEach( Iterable<T> objects )
+    {
+        return toXmlEach( Options.DEFAULT, StreamSupport.stream( 
objects.spliterator(), false ) );
+    }
+
+    default <T> Stream<Document> toXmlEach( Object... objects )
+    {
+        return toXmlEach( Options.DEFAULT, Stream.of( objects ) );
+    }
+
+    default void serialize( Options options, Writer writer, @Optional Object 
object )
+    {
+        Document xmlDocument = toXml( options, object );
+        if( xmlDocument == null )
+        {
+            return;
+        }
+        try
+        {
+            // We want plain Strings to be serialized without quotes
+            if( xmlDocument.getNodeType() == Node.TEXT_NODE )
+            {
+                writer.write( xmlDocument.getNodeValue() );
+            }
+            else
+            {
+                Transformer transformer = 
TransformerFactory.newInstance().newTransformer();
+                transformer.transform( new DOMSource( xmlDocument ), new 
StreamResult( writer ) );
+            }
+        }
+        catch( IOException ex )
+        {
+            throw new UncheckedIOException( ex );
+        }
+        catch( TransformerException ex )
+        {
+            throw new SerializationException( "Unable to transform XML 
Document to String", ex );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/serialization/package.html
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/package.html 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/package.html
new file mode 100644
index 0000000..2e2f188
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/spi/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.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/types/ValueTypeFactory.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/types/ValueTypeFactory.java 
b/core/spi/src/main/java/org/apache/polygene/spi/types/ValueTypeFactory.java
new file mode 100644
index 0000000..efe2c3b
--- /dev/null
+++ b/core/spi/src/main/java/org/apache/polygene/spi/types/ValueTypeFactory.java
@@ -0,0 +1,11 @@
+package org.apache.polygene.spi.types;
+
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.ValueType;
+
+public interface ValueTypeFactory
+{
+    ValueType valueTypeOf( ModuleDescriptor module, Object object );
+
+    ValueType valueTypeOf( ModuleDescriptor module, Class<?> type );
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/value/ValueDeserializerAdapter.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/value/ValueDeserializerAdapter.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/value/ValueDeserializerAdapter.java
deleted file mode 100644
index cac2270..0000000
--- 
a/core/spi/src/main/java/org/apache/polygene/spi/value/ValueDeserializerAdapter.java
+++ /dev/null
@@ -1,1000 +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.spi.value;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-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.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
-import org.apache.polygene.api.structure.ModuleDescriptor;
-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.Serialization;
-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.api.value.ValueDescriptor;
-import org.apache.polygene.api.value.ValueDeserializer;
-import org.apache.polygene.api.value.ValueSerializationException;
-
-/**
- * Adapter for pull-parsing and tree-parsing capable ValueDeserializers.
- *
- * <p>
- * Among Plain values (see {@link ValueDeserializer}) some are considered 
primitives to underlying serialization
- * mechanisms and by so handed/come without conversion to/from 
implementations. Primitive values can be one of:
- * </p>
- * <ul>
- * <li>String,</li>
- * <li>Character or char,</li>
- * <li>Boolean or boolean,</li>
- * <li>Integer or int,</li>
- * <li>Long or long,</li>
- * <li>Short or short,</li>
- * <li>Byte or byte,</li>
- * <li>Float or float,</li>
- * <li>Double or double.</li>
- * </ul>
- * <p>
- * Some other Plain values are expected in given formats:
- * </p>
- * <ul>
- * <li>BigInteger and BigDecimal depends on {@link 
org.apache.polygene.api.value.ValueSerializer.Options};</li>
- * <li>Date as String in ISO-8601, {@literal @millis@} or {@literal /Date(..)} 
Microsoft format;</li>
- * <li>DateTime (JodaTime) as a ISO-8601 String with optional timezone 
offset;</li>
- * <li>LocalDateTime (JodaTime) as whatever {@link LocalDateTime#parse} accept 
as {@literal instant};</li>
- * <li>LocalDate (JodaTime) as whatever {@link LocalDate#parse} accept as 
{@literal instant};</li>
- * </ul>
- *
- * @param <InputType>     Implementor pull-parser type
- * @param <InputNodeType> Implementor tree-parser node type
- */
-public abstract class ValueDeserializerAdapter<InputType, InputNodeType>
-    implements ValueDeserializer
-{
-    public interface ComplexDeserializer<T, InputType, InputNodeType>
-    {
-        T deserializePull( InputType input )
-            throws Exception;
-
-        T deserializeTree( InputNodeType inputNode )
-            throws Exception;
-    }
-
-    private static final String UTF_8 = "UTF-8";
-    private final Map<Class<?>, Function<Object, Object>> deserializers = new 
HashMap<>( 16 );
-    private final Map<Class<?>, ComplexDeserializer<Object, InputType, 
InputNodeType>> complexDeserializers = new HashMap<>( 2 );
-
-    /**
-     * Register a Plain Value type deserialization Function.
-     *
-     * @param <T>          Plain Value parametrized Type
-     * @param type         Plain Value Type
-     * @param deserializer Deserialization Function
-     */
-    @SuppressWarnings( "unchecked" )
-    protected final <T> void registerDeserializer( Class<T> type, 
Function<Object, T> deserializer )
-    {
-        deserializers.put( type, (Function<Object, Object>) deserializer );
-    }
-
-    @SuppressWarnings( { "UnusedDeclaration", "unchecked" } )
-    protected final <T> void registerComplexDeserializer( Class<T> type,
-                                                          
ComplexDeserializer<T, InputType, InputNodeType> deserializer
-    )
-    {
-        complexDeserializers.put( type, (ComplexDeserializer<Object, 
InputType, InputNodeType>) deserializer );
-    }
-
-    protected ValueDeserializerAdapter()
-    {
-
-        // Primitive Value types
-        registerDeserializer( String.class, Object::toString );
-        registerDeserializer( Character.class, input -> 
input.toString().charAt( 0 ) );
-        registerDeserializer( Boolean.class, input -> ( input instanceof 
String )
-                                                      ? Boolean.parseBoolean( 
(String) input )
-                                                      : (Boolean) input );
-        registerDeserializer( Integer.class, input -> ( input instanceof 
String )
-                                                      ? Integer.parseInt( 
(String) input )
-                                                      : ( (Number) input 
).intValue() );
-        registerDeserializer( Long.class, input -> ( input instanceof String )
-                                                   ? Long.parseLong( (String) 
input )
-                                                   : ( (Number) input 
).longValue() );
-        registerDeserializer( Short.class, input -> ( input instanceof String )
-                                                    ? Short.parseShort( 
(String) input )
-                                                    : ( (Number) input 
).shortValue() );
-        registerDeserializer( Byte.class, input -> ( input instanceof String )
-                                                   ? Byte.parseByte( (String) 
input )
-                                                   : ( (Number) input 
).byteValue() );
-        registerDeserializer( Float.class, input -> ( input instanceof String )
-                                                    ? Float.parseFloat( 
(String) input )
-                                                    : ( (Number) input 
).floatValue() );
-        registerDeserializer( Double.class, input -> ( input instanceof String 
)
-                                                     ? Double.parseDouble( 
(String) input )
-                                                     : ( (Number) input 
).doubleValue() );
-
-        // Number types
-        registerDeserializer( BigDecimal.class, input -> new BigDecimal( 
input.toString() ) );
-        registerDeserializer( BigInteger.class, input -> new BigInteger( 
input.toString() ) );
-        registerDeserializer( Identity.class, input -> 
StringIdentity.fromString( input.toString() ) );
-
-        // Date types
-        registerDeserializer( Instant.class, input -> Instant.parse( 
input.toString() ) );
-        registerDeserializer( ZonedDateTime.class, input -> 
ZonedDateTime.parse( input.toString() ) );
-        registerDeserializer( OffsetDateTime.class, input -> 
OffsetDateTime.parse( input.toString() ) );
-        registerDeserializer( LocalDateTime.class, input -> 
LocalDateTime.parse( input.toString() ) );
-        registerDeserializer( LocalDate.class, input -> LocalDate.parse( 
input.toString() ));
-        registerDeserializer( LocalTime.class, input -> LocalTime.parse( 
input.toString() ));
-        registerDeserializer( Duration.class, input -> Duration.parse( 
input.toString() ));
-        registerDeserializer( Period.class, input -> Period.parse( 
input.toString() ));
-
-        // Other supported types
-        registerDeserializer( EntityReference.class, input -> 
EntityReference.parseEntityReference( input.toString() ) );
-    }
-
-    @Override
-    public <T> Function<String, T> deserialize( ModuleDescriptor module, 
Class<T> type )
-    {
-        if( CollectionType.isCollection( type ) )
-        {
-            ValueType objectValueType = new ValueType( Object.class );
-            return deserialize( module, new CollectionType( type, 
objectValueType ) );
-        }
-        if( MapType.isMap( type ) )
-        {
-            ValueType objectValueType = new ValueType( Object.class );
-            return deserialize( module, new MapType( type, objectValueType, 
objectValueType ) );
-        }
-        return deserialize( module, new ValueType( type ) );
-    }
-
-    @Override
-    public final <T> Function<String, T> deserialize( ModuleDescriptor module, 
ValueType valueType )
-    {
-        return input -> deserialize( module, valueType, input );
-    }
-
-    @Override
-    public final <T> T deserialize( ModuleDescriptor module, Class<?> type, 
String input )
-        throws ValueSerializationException
-    {
-        if( CollectionType.isCollection( type ) )
-        {
-            ValueType objectValueType = new ValueType( Object.class );
-            return deserialize( module, new CollectionType( type, 
objectValueType ), input );
-        }
-        if( MapType.isMap( type ) )
-        {
-            ValueType objectValueType = new ValueType( Object.class );
-            return deserialize( module, new MapType( type, objectValueType, 
objectValueType ), input );
-        }
-        return deserialize( module, new ValueType( type ), input );
-    }
-
-    @Override
-    public final <T> T deserialize( ModuleDescriptor module, ValueType 
valueType, String input )
-        throws ValueSerializationException
-    {
-        try
-        {
-            return deserializeRoot( module, valueType, new 
ByteArrayInputStream( input.getBytes( UTF_8 ) ) );
-        }
-        catch( ValueSerializationException ex )
-        {
-            throw ex;
-        }
-        catch( Exception ex )
-        {
-            throw new ValueSerializationException( "Could not deserialize 
value", ex );
-        }
-    }
-
-    @Override
-    public final <T> T deserialize( ModuleDescriptor module, Class<?> type, 
InputStream input )
-        throws ValueSerializationException
-    {
-        if( CollectionType.isCollection( type ) )
-        {
-            ValueType objectValueType = new ValueType( Object.class );
-            return deserialize( module, new CollectionType( type, 
objectValueType ), input );
-        }
-        if( MapType.isMap( type ) )
-        {
-            ValueType objectValueType = new ValueType( Object.class );
-            return deserialize( module, new MapType( type, objectValueType, 
objectValueType ), input );
-        }
-        return deserialize( module, new ValueType( type ), input );
-    }
-
-    @Override
-    public final <T> T deserialize( ModuleDescriptor module, ValueType 
valueType, InputStream input )
-        throws ValueSerializationException
-    {
-        try
-        {
-            return deserializeRoot( module, valueType, input );
-        }
-        catch( ValueSerializationException ex )
-        {
-            throw ex;
-        }
-        catch( Exception ex )
-        {
-            throw new ValueSerializationException( "Could not deserialize 
value", ex );
-        }
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T deserializeRoot( ModuleDescriptor module, ValueType 
valueType, InputStream input )
-        throws Exception
-    {
-        Class<?> type = valueType.types().findFirst().orElse( null );
-
-        if( Identity.class.isAssignableFrom( type ) )
-        {
-            type = Identity.class;
-        }
-
-        // Plain ValueType
-        Function<Object, Object> deserializationFunction = deserializers.get( 
type );
-        if( deserializationFunction != null )
-        {
-            Scanner scanner = new Scanner( input, UTF_8 ).useDelimiter( "\\A" 
);
-            if( !scanner.hasNext() )
-            {
-                return String.class.equals( type ) ? (T) "" : null;
-            }
-            String string = scanner.next();
-            return (T) deserializationFunction.apply( string );
-        }
-        else // Array ValueType
-            if( type.isArray() )
-            {
-                Scanner scanner = new Scanner( input, UTF_8 ).useDelimiter( 
"\\A" );
-                if( !scanner.hasNext() )
-                {
-                    return null;
-                }
-                String string = scanner.next();
-                return (T) deserializeBase64Serialized( module, string );
-            }
-            else if( type.isEnum() )
-            {
-                Scanner scanner = new Scanner( input, UTF_8 ).useDelimiter( 
"\\A" );
-                if( !scanner.hasNext() )
-                {
-                    return String.class.equals( type ) ? (T) "" : null;
-                }
-                String string = scanner.next();
-                return (T) Enum.valueOf( (Class) type, string );
-            }
-            else // Complex ValueType
-            {
-                InputType adaptedInput = adaptInput( module, input );
-                onDeserializationStart( module, valueType, adaptedInput );
-                T deserialized = doDeserialize( module, valueType, 
adaptedInput );
-                onDeserializationEnd( module, valueType, adaptedInput );
-                return deserialized;
-            }
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T doDeserialize( ModuleDescriptor module, ValueType valueType, 
InputType input )
-        throws Exception
-    {
-        final Class<?> type = valueType.types().findFirst().orElse( null );
-        // Registered deserializers
-        if( deserializers.get( type ) != null )
-        {
-            Object value = readPlainValue( module, input );
-            if( value == null )
-            {
-                return null;
-            }
-            return (T) deserializers.get( type ).apply( value );
-        }
-        else if( complexDeserializers.get( type ) != null )
-        {
-            return (T) complexDeserializers.get( type ).deserializePull( input 
);
-        }
-        else // Explicit ValueComposite
-            if( ValueCompositeType.class.isAssignableFrom( 
valueType.getClass() ) )
-            {
-                return (T) deserializeValueComposite( module, valueType, input 
);
-            }
-            else // Explicit Collections
-                if( CollectionType.class.isAssignableFrom( 
valueType.getClass() ) )
-                {
-                    return (T) deserializeCollection( module, (CollectionType) 
valueType, input );
-                }
-                else // Explicit Map
-                    if( MapType.class.isAssignableFrom( valueType.getClass() ) 
)
-                    {
-                        return (T) deserializeMap( module, (MapType) 
valueType, input );
-                    }
-                    else // Enum
-                        if( EnumType.class.isAssignableFrom( 
valueType.getClass() ) || type.isEnum() )
-                        {
-                            return (T) Enum.valueOf( (Class) type, 
readPlainValue( module, input ).toString() );
-                        }
-                        else // Array
-                            if( type.isArray() )
-                            {
-                                return (T) deserializeBase64Serialized( 
module, readPlainValue( module, input ).toString() );
-                            }
-        // Guessed Deserialization
-        return (T) deserializeGuessed( module, valueType, input );
-    }
-
-    private <T> Function<InputType, T> buildDeserializeInputFunction( 
ModuleDescriptor module, ValueType valueType )
-    {
-        return input -> {
-            try
-            {
-                return doDeserialize( module, valueType, input );
-            }
-            catch( ValueSerializationException ex )
-            {
-                throw ex;
-            }
-            catch( Exception ex )
-            {
-                throw new ValueSerializationException( ex );
-            }
-        };
-    }
-
-    private <T> Collection<T> deserializeCollection( ModuleDescriptor module, 
CollectionType collectionType, InputType input )
-        throws Exception
-    {
-        Collection<T> collection;
-        Class<?> collectionMainType = 
collectionType.types().findFirst().orElse( null );
-        if( Set.class.equals( collectionMainType ) )
-        {
-            collection = new LinkedHashSet<>();
-        }
-        else
-        {
-            collection = new ArrayList<>();
-        }
-        return readArrayInCollection( module,
-                                      input,
-                                      this.buildDeserializeInputFunction( 
module, collectionType.collectedType() ),
-                                      collection );
-    }
-
-    private <K, V> Map<K, V> deserializeMap( ModuleDescriptor module, MapType 
mapType, InputType input )
-        throws Exception
-    {
-        return readMapInMap( module,
-                             input,
-                             this.<K>buildDeserializeInputFunction( module, 
mapType.keyType() ),
-                             this.<V>buildDeserializeInputFunction( module, 
mapType.valueType() ),
-                             new HashMap<>() );
-    }
-
-    private <T> T deserializeValueComposite( ModuleDescriptor module, 
ValueType valueType, InputType input )
-        throws Exception
-    {
-        InputNodeType inputNode = readObjectTree( module, input );
-        if( inputNode == null )
-        {
-            return null;
-        }
-        return deserializeNodeValueComposite( module, valueType, inputNode );
-    }
-
-    private <T> T deserializeNodeValueComposite( ModuleDescriptor module, 
ValueType valueType, InputNodeType inputNode )
-        throws Exception
-    {
-        ValueCompositeType valueCompositeType = (ValueCompositeType) valueType;
-        Class<?> valueBuilderType = 
valueCompositeType.types().findFirst().orElse( null );
-        String typeInfo = this.getObjectFieldValue(
-            module,
-            inputNode,
-            "_type",
-            this.<String>buildDeserializeInputNodeFunction( module, new 
ValueType( String.class ) ) );
-        if( typeInfo != null )
-        {
-            ValueDescriptor valueDescriptor = module.valueDescriptor( typeInfo 
);
-            if( valueDescriptor == null )
-            {
-                throw new ValueSerializationException( "Specified value type 
could not be resolved: " + typeInfo );
-            }
-            valueCompositeType = valueDescriptor.valueType();
-            valueBuilderType = Class.forName( typeInfo );
-        }
-        return deserializeValueComposite( module, valueCompositeType, 
valueBuilderType, inputNode );
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T deserializeValueComposite( ModuleDescriptor module,
-                                             ValueCompositeType 
valueCompositeType,
-                                             Class<?> valueBuilderType,
-                                             InputNodeType inputNode
-    )
-        throws Exception
-    {
-        final Map<String, Object> stateMap = new HashMap<>();
-
-        // Properties
-        valueCompositeType.properties().forEach( property -> {
-            String propertyName = null;
-            Object value;
-            try
-            {
-                propertyName = property.qualifiedName().name();
-                if( objectHasField( module, inputNode, propertyName ) )
-                {
-                    value = getObjectFieldValue(
-                        module,
-                        inputNode,
-                        propertyName,
-                        buildDeserializeInputNodeFunction( module, 
property.valueType() ) );
-                    if( property.isImmutable() )
-                    {
-                        if( value instanceof Set )
-                        {
-                            value = Collections.unmodifiableSet( (Set<?>) 
value );
-                        }
-                        else if( value instanceof List )
-                        {
-                            value = Collections.unmodifiableList( (List<?>) 
value );
-                        }
-                        else if( value instanceof Map )
-                        {
-                            value = Collections.unmodifiableMap( (Map<?, ?>) 
value );
-                        }
-                    }
-                }
-                else
-                {
-                    // Serialized object does not contain the field, try to 
default it
-                    value = property.initialValue( module );
-                }
-            }
-            catch( Exception e )
-            {
-                throw new ValueSerializationException( "Unable to deserialize 
property " + property, e );
-            }
-            stateMap.put( propertyName, value );
-        } );
-
-        // Associations
-        valueCompositeType.associations().forEach( association -> {
-            try
-            {
-                String associationName = association.qualifiedName().name();
-                if( objectHasField( module, inputNode, associationName ) )
-                {
-                    Object value = getObjectFieldValue(
-                        module,
-                        inputNode,
-                        associationName,
-                        buildDeserializeInputNodeFunction( module, new 
ValueType( EntityReference.class ) ) );
-                    stateMap.put( associationName, value );
-                }
-            }
-            catch( Exception e )
-            {
-                throw new ValueSerializationException( "Unable to deserialize 
association " + association, e );
-            }
-        } );
-
-        // ManyAssociations
-        valueCompositeType.manyAssociations().forEach( manyAssociation -> {
-            try
-            {
-                String manyAssociationName = 
manyAssociation.qualifiedName().name();
-                if( objectHasField( module, inputNode, manyAssociationName ) )
-                {
-                    Object value = getObjectFieldValue(
-                        module,
-                        inputNode,
-                        manyAssociationName,
-                        buildDeserializeInputNodeFunction(
-                            module,
-                            new CollectionType(
-                                Collection.class,
-                                new ValueType( EntityReference.class ) ) ) );
-                    stateMap.put( manyAssociationName, value );
-                }
-            }
-            catch( Exception e )
-            {
-                throw new ValueSerializationException( "Unable to deserialize 
manyassociation " + manyAssociation, e );
-            }
-        } );
-
-        // NamedAssociations
-        valueCompositeType.namedAssociations().forEach( namedAssociation -> {
-            try
-            {
-                String namedAssociationName = 
namedAssociation.qualifiedName().name();
-                if( objectHasField( module, inputNode, namedAssociationName ) )
-                {
-                    Object value = getObjectFieldValue(
-                        module,
-                        inputNode,
-                        namedAssociationName,
-                        buildDeserializeInputNodeFunction( module, MapType.of( 
String.class, EntityReference.class, Serialization.Variant.object ) ) );
-                    stateMap.put( namedAssociationName, value );
-                }
-            }
-            catch( Exception e )
-            {
-                throw new ValueSerializationException( "Unable to deserialize 
namedassociation " + namedAssociation, e );
-            }
-        } );
-
-        ValueBuilder<?> valueBuilder = buildNewValueBuilderWithState( module, 
valueBuilderType, stateMap );
-        return (T) valueBuilder.newInstance(); // Unchecked cast because the 
builder could use a type != T
-    }
-
-    private <T> Function<InputNodeType, T> buildDeserializeInputNodeFunction( 
ModuleDescriptor module, final ValueType valueType )
-    {
-        return inputNode -> {
-            try
-            {
-                return doDeserializeInputNodeValue( module, valueType, 
inputNode );
-            }
-            catch( ValueSerializationException ex )
-            {
-                throw ex;
-            }
-            catch( Exception ex )
-            {
-                throw new ValueSerializationException( ex );
-            }
-        };
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T doDeserializeInputNodeValue( ModuleDescriptor module, 
ValueType valueType, InputNodeType inputNode )
-        throws Exception
-    {
-        if( inputNode == null )
-        {
-            return null;
-        }
-        final Class<?> type = valueType.types().findFirst().orElse( null );
-        // Registered deserializers
-        if( deserializers.get( type ) != null )
-        {
-            Object value = asSimpleValue( module, inputNode );
-            if( value == null )
-            {
-                return null;
-            }
-            return (T) deserializers.get( type ).apply( value );
-        }
-        else if( complexDeserializers.get( type ) != null )
-        {
-            return (T) complexDeserializers.get( type ).deserializeTree( 
inputNode );
-        }
-        else // Explicit ValueComposite
-            if( ValueCompositeType.class.isAssignableFrom( 
valueType.getClass() ) )
-            {
-                return (T) deserializeNodeValueComposite( module, valueType, 
inputNode );
-            }
-            else // Explicit Collections
-                if( CollectionType.class.isAssignableFrom( 
valueType.getClass() ) )
-                {
-                    return (T) deserializeNodeCollection( module, 
(CollectionType) valueType, inputNode );
-                }
-                else // Explicit Map
-                    if( MapType.class.isAssignableFrom( valueType.getClass() ) 
)
-                    {
-                        MapType mapType = (MapType) valueType;
-                        if( mapType.variant().equals( 
Serialization.Variant.entry ) )
-                        {
-                            return (T) deserializeNodeEntryMap( module, 
(MapType) valueType, inputNode );
-                        }
-                        else
-                        {
-                            return (T) deserializeNodeObjectMap( module, 
(MapType) valueType, inputNode );
-                        }
-                    }
-                    else // Enum
-                        if( EnumType.class.isAssignableFrom( 
valueType.getClass() ) || type.isEnum() )
-                        {
-                            Object value = asSimpleValue( module, inputNode );
-                            if( value == null )
-                            {
-                                return null;
-                            }
-                            return (T) Enum.valueOf( (Class) type, 
value.toString() );
-                        }
-        // Guessed deserialization
-        return (T) deserializeNodeGuessed( module, valueType, inputNode );
-    }
-
-    private ValueBuilder<?> buildNewValueBuilderWithState( ModuleDescriptor 
module,
-                                                           Class<?> type,
-                                                           final Map<String, 
Object> stateMap
-    )
-    {
-        return module.instance().newValueBuilderWithState(
-            type,
-            property -> stateMap.get( property.qualifiedName().name() ),
-            association -> {
-                Object entityRef = stateMap.get( 
association.qualifiedName().name() );
-                if( entityRef == null )
-                {
-                    return null;
-                }
-                return (EntityReference) entityRef;
-            },
-            manyAssociation -> {
-                Object entityRefs = stateMap.get( 
manyAssociation.qualifiedName().name() );
-                if( entityRefs == null )
-                {
-                    return Stream.empty();
-                }
-                //noinspection unchecked
-                return StreamSupport.stream( ( (Iterable<EntityReference>) 
entityRefs ).spliterator(), false );
-            },
-            namedAssociation -> {
-                Object entityRefs = stateMap.get( 
namedAssociation.qualifiedName().name() );
-                if( entityRefs == null )
-                {
-                    return Stream.empty();
-                }
-                //noinspection unchecked
-                return ( (Map<String, EntityReference>) entityRefs 
).entrySet().stream();
-            } );
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T deserializeGuessed( ModuleDescriptor module, ValueType 
valueType, InputType input )
-        throws Exception
-    {
-        InputNodeType inputNode = readObjectTree( module, input );
-        if( inputNode == null )
-        {
-            return null;
-        }
-        return deserializeNodeGuessed( module, valueType, inputNode );
-    }
-
-    private <T> Collection<T> deserializeNodeCollection( ModuleDescriptor 
module,
-                                                         CollectionType 
collectionType,
-                                                         InputNodeType 
inputNode
-    )
-        throws Exception
-    {
-        Collection<T> collection;
-        Class<?> collectionMainType = 
collectionType.types().findFirst().orElse( null );
-        if( Set.class.equals( collectionMainType ) )
-        {
-            collection = new LinkedHashSet<>();
-        }
-        else
-        {
-            collection = new ArrayList<>();
-        }
-        putArrayNodeInCollection( module,
-                                  inputNode,
-                                  this.buildDeserializeInputNodeFunction( 
module, collectionType.collectedType() ),
-                                  collection );
-        return collection;
-    }
-
-    private <K, V> Map<K, V> deserializeNodeEntryMap( ModuleDescriptor module, 
MapType mapType, InputNodeType inputNode )
-        throws Exception
-    {
-        Map<K, V> map = new HashMap<>();
-        putArrayNodeInMap( module,
-                           inputNode,
-                           this.buildDeserializeInputNodeFunction( module, 
mapType.keyType() ),
-                           this.buildDeserializeInputNodeFunction( module, 
mapType.valueType() ),
-                           map );
-        return map;
-    }
-
-    private <V> Map<String, V> deserializeNodeObjectMap( ModuleDescriptor 
module, MapType mapType, InputNodeType inputNode )
-        throws Exception
-    {
-        Map<String, V> map = new HashMap<>();
-        putObjectNodeInMap( module,
-                            inputNode,
-                            this.buildDeserializeInputNodeFunction( module, 
mapType.valueType() ),
-                            map );
-        return map;
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T deserializeNodeGuessed( ModuleDescriptor module, ValueType 
valueType, InputNodeType inputNode )
-        throws Exception
-    {
-        if( isObjectValue( module, inputNode ) )
-        {
-            // Attempt ValueComposite deserialization
-            ValueCompositeType valueCompositeType;
-            if( objectHasField( module, inputNode, "_type" ) ) // with _type 
info
-            {
-                String typeInfo = this.getObjectFieldValue(
-                    module,
-                    inputNode,
-                    "_type",
-                    this.<String>buildDeserializeInputNodeFunction( module, 
new ValueType( String.class ) ) );
-                ValueDescriptor valueDescriptor = module.valueDescriptor( 
typeInfo );
-                if( valueDescriptor == null )
-                {
-                    throw new ValueSerializationException( "Specified value 
type could not be resolved: " + typeInfo );
-                }
-                valueCompositeType = valueDescriptor.valueType();
-            }
-            else // without _type info
-            {
-                ValueDescriptor valueDescriptor = module.valueDescriptor( 
valueType.types()
-                                                                              
.findFirst()
-                                                                              
.get()
-                                                                              
.getName() );
-                if( valueDescriptor == null )
-                {
-                    throw new ValueSerializationException( "Don't know how to 
deserialize " + inputNode );
-                }
-                valueCompositeType = valueDescriptor.valueType();
-            }
-            Class<?> valueBuilderType = 
valueCompositeType.types().findFirst().orElse( null );
-            return deserializeValueComposite( module, valueCompositeType, 
valueBuilderType, inputNode );
-        }
-        // Last resort : base64 java deserialization
-        return (T) deserializeBase64Serialized( module, inputNode );
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T deserializeBase64Serialized( ModuleDescriptor module, 
InputNodeType inputNode )
-        throws Exception
-    {
-        Object value = asSimpleValue( module, inputNode );
-        if( value == null )
-        {
-            return null;
-        }
-        String base64 = value.toString();
-        return deserializeBase64Serialized( module, base64 );
-    }
-
-    @SuppressWarnings( "unchecked" )
-    private <T> T deserializeBase64Serialized( ModuleDescriptor module, String 
inputString )
-        throws Exception
-    {
-        byte[] bytes = inputString.getBytes( UTF_8 );
-        bytes = Base64.getDecoder().decode( bytes );
-        Object result;
-        try (ObjectInputStream oin = new ObjectInputStream( new 
ByteArrayInputStream( bytes ) ))
-        {
-            result = oin.readObject();
-        }
-        return (T) result;
-    }
-
-    //
-    // Deserialization Extension Points
-    //
-
-    /**
-     * Called by the adapter on deserialization start, after {@link 
#adaptInput(ModuleDescriptor, java.io.InputStream)}.
-     *
-     * @param module    Module descriptor
-     * @param valueType ValueType
-     * @param input     Input
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    @SuppressWarnings( "UnusedParameters" )
-    protected void onDeserializationStart( ModuleDescriptor module, ValueType 
valueType, InputType input )
-        throws Exception
-    {
-        // NOOP
-    }
-
-    /**
-     * Called by the adapter on deserialization end.
-     *
-     * @param module    Module descriptor
-     * @param valueType ValueType
-     * @param input     Input
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected void onDeserializationEnd( ModuleDescriptor module, ValueType 
valueType, InputType input )
-        throws Exception
-    {
-        // NOOP
-    }
-
-    //
-    // Pull Parsing Deserialization
-    //
-
-    /**
-     * This method is always called first, this is a chance to wrap the input 
type.
-     *
-     * @param module Module descriptor
-     * @param input  InputStream to adapt
-     *
-     * @return Adapted input
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected abstract InputType adaptInput( ModuleDescriptor module, 
InputStream input )
-        throws Exception;
-
-    /**
-     * @param module Module descriptor
-     * @param input  Input
-     *
-     * @return a Plain Value read from the input
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected abstract Object readPlainValue( ModuleDescriptor module, 
InputType input )
-        throws Exception;
-
-    /**
-     * @param module       Module descriptor
-     * @param input        Input
-     * @param deserializer Deserialization function
-     * @param collection   Collection
-     * @param <T>          Parameterized collection type
-     *
-     * @return The filled collection or null if no array
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected abstract <T> Collection<T> readArrayInCollection( 
ModuleDescriptor module,
-                                                                InputType 
input,
-                                                                
Function<InputType, T> deserializer,
-                                                                Collection<T> 
collection
-    )
-        throws Exception;
-
-    /**
-     * A Map&lt;K,V&gt; is serialized in an array of entries objects.
-     *
-     * <p>Here is an example in JSON:</p>
-     * <pre>
-     * [
-     *     { "key": "foo",       "value": "bar"   },
-     *     { "key": "cathedral", "value": "bazar" }
-     * ]
-     * </pre>
-     * <p>And an empty Map:</p>
-     * <pre>[]</pre>
-     * <p>
-     * This allow to use any type as keys and values while keeping the Map 
order at the cost of having
-     * non-predictible order of key/value inside an entry object.
-     * </p>
-     *
-     * @param module            Module descriptor
-     * @param input             Input
-     * @param keyDeserializer   Map key deserialization function
-     * @param valueDeserializer Map value deserialization function
-     * @param map               Map
-     * @param <K>               Parameterized map key type
-     * @param <V>               Parameterized map value type
-     *
-     * @return The filled map or null if no array
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected abstract <K, V> Map<K, V> readMapInMap( ModuleDescriptor module,
-                                                      InputType input,
-                                                      Function<InputType, K> 
keyDeserializer,
-                                                      Function<InputType, V> 
valueDeserializer,
-                                                      Map<K, V> map
-    )
-        throws Exception;
-
-    /**
-     * @param module Module descriptor
-     * @param input  Input
-     *
-     * @return an InputNodeType or null if the value was null
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected abstract InputNodeType readObjectTree( ModuleDescriptor module, 
InputType input )
-        throws Exception;
-
-    //
-    // Tree Parsing Deserialization
-    //
-    protected abstract Object asSimpleValue( ModuleDescriptor module, 
InputNodeType inputNode )
-        throws Exception;
-
-    protected abstract boolean isObjectValue( ModuleDescriptor module, 
InputNodeType inputNode )
-        throws Exception;
-
-    protected abstract boolean objectHasField( ModuleDescriptor module, 
InputNodeType inputNode, String key )
-        throws Exception;
-
-    /**
-     * Return null if the field do not exists.
-     *
-     * @param module            Module descriptor
-     * @param inputNode         Input Node
-     * @param key               Object key
-     * @param valueDeserializer Deserialization function
-     * @param <T>               Parameterized object field value type
-     *
-     * @return The value of the field.
-     *
-     * @throws Exception that will be wrapped in a {@link 
ValueSerializationException}
-     */
-    protected abstract <T> T getObjectFieldValue( ModuleDescriptor module,
-                                                  InputNodeType inputNode,
-                                                  String key,
-                                                  Function<InputNodeType, T> 
valueDeserializer
-    )
-        throws Exception;
-
-    protected abstract <T> void putArrayNodeInCollection( ModuleDescriptor 
module,
-                                                          InputNodeType 
inputNode,
-                                                          
Function<InputNodeType, T> deserializer,
-                                                          Collection<T> 
collection
-    )
-        throws Exception;
-
-    protected abstract <K, V> void putArrayNodeInMap( ModuleDescriptor module,
-                                                      InputNodeType inputNode,
-                                                      Function<InputNodeType, 
K> keyDeserializer,
-                                                      Function<InputNodeType, 
V> valueDeserializer,
-                                                      Map<K, V> map
-    )
-        throws Exception;
-
-    protected abstract <V> void putObjectNodeInMap( ModuleDescriptor module,
-                                                    InputNodeType inputNode,
-                                                    Function<InputNodeType, V> 
valueDeserializer,
-                                                    Map<String, V> map
-    )
-        throws Exception;
-}

Reply via email to