You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2015/04/17 18:05:35 UTC

[15/50] [abbrv] zest-qi4j git commit: Merge branch 'feature/valueserialization-spi' into develop

Merge branch 'feature/valueserialization-spi' into develop

Conflicts:
	core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
	core/api/src/main/java/org/qi4j/api/json/JSONDeserializer.java
	core/api/src/main/java/org/qi4j/api/json/JSONObjectSerializer.java
	core/api/src/main/java/org/qi4j/api/json/JSONSerializer.java
	core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithPrototype.java
	core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
	core/runtime/src/test/java/org/qi4j/runtime/types/JodaDateTimeTypeTest.java
	core/runtime/src/test/java/org/qi4j/runtime/types/JodaLocalDateTimeTypeTest.java
	core/runtime/src/test/java/org/qi4j/runtime/types/JodaLocalDateTypeTest.java
	core/runtime/src/test/java/org/qi4j/runtime/value/CollectionTypeTest.java
	core/spi/src/docs/spi.txt
	core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONEntityState.java
	extensions/entitystore-gae/src/main/java/org/qi4j/entitystore/gae/GaeEntityState.java
	extensions/entitystore-neo4j/src/main/java/org/qi4j/entitystore/neo4j/NeoEntityState.java
	extensions/entitystore-preferences/src/main/java/org/qi4j/entitystore/prefs/PreferencesEntityStoreMixin.java
	extensions/indexing-elasticsearch/src/main/java/org/qi4j/index/elasticsearch/ElasticSearchIndexer.java
	extensions/indexing-rdf/src/main/java/org/qi4j/index/rdf/query/internal/RdfQueryParserImpl2.java
	libraries/rdf/src/main/java/org/qi4j/library/rdf/entity/EntityStateSerializer.java
	libraries/rest-client/src/main/java/org/qi4j/library/rest/client/requestwriter/ValueCompositeRequestWriter.java
	libraries/rest/src/main/java/org/qi4j/library/rest/admin/EntityResource.java
	samples/dci-cargo/dcisample_a/src/main/java/org/qi4j/sample/dcicargo/sample_a/infrastructure/model/JSONModel.java
	samples/dci-cargo/dcisample_b/src/main/java/org/qi4j/sample/dcicargo/sample_b/infrastructure/model/JSONModel.java


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

Branch: refs/heads/master
Commit: e2ea757e55ca76702d92b5cfeb62247b9bc6bb41
Parents: 59959ca e428fa9
Author: Paul Merlin <pa...@nosphere.org>
Authored: Wed Feb 13 11:47:48 2013 +0100
Committer: Paul Merlin <pa...@nosphere.org>
Committed: Wed Feb 13 11:47:48 2013 +0100

----------------------------------------------------------------------
 build.gradle                                    |    2 +-
 core/api/build.gradle                           |    1 +
 core/api/src/docs/valuecomposite.txt            |  121 +-
 core/api/src/main/java/org/json/JSONArray.java  | 1195 -----------
 .../src/main/java/org/json/JSONException.java   |   45 -
 core/api/src/main/java/org/json/JSONObject.java | 1904 ------------------
 core/api/src/main/java/org/json/JSONString.java |   34 -
 .../src/main/java/org/json/JSONStringer.java    |   95 -
 .../api/src/main/java/org/json/JSONTokener.java |  501 -----
 core/api/src/main/java/org/json/JSONWriter.java |  429 ----
 core/api/src/main/java/org/json/package.html    |    8 -
 .../org/qi4j/api/composite/PropertyMapper.java  |    3 +-
 .../java/org/qi4j/api/json/Base64Encoder.java   |  224 ---
 .../org/qi4j/api/json/JSONDeserializer.java     |  528 -----
 .../org/qi4j/api/json/JSONObjectSerializer.java |   92 -
 .../java/org/qi4j/api/json/JSONSerializer.java  |  335 ---
 .../org/qi4j/api/json/JSONWriterSerializer.java |   83 -
 .../main/java/org/qi4j/api/json/package.html    |    5 -
 .../java/org/qi4j/api/type/CollectionType.java  |   22 +-
 .../main/java/org/qi4j/api/type/EnumType.java   |   13 +-
 .../main/java/org/qi4j/api/type/MapType.java    |   16 +-
 .../main/java/org/qi4j/api/type/ValueType.java  |   97 +-
 .../java/org/qi4j/api/util/Base64Encoder.java   |  224 +++
 .../org/qi4j/api/value/ValueBuilderFactory.java |    6 +-
 .../org/qi4j/api/value/ValueDeserializer.java   |  151 ++
 .../org/qi4j/api/value/ValueSerialization.java  |   48 +
 .../api/value/ValueSerializationException.java  |   46 +
 .../org/qi4j/api/value/ValueSerializer.java     |  129 ++
 .../api/configuration/ConfigurationTest.java    |    4 +-
 .../DeclareConfigurationDefaultsTest.java       |    7 +-
 .../dataset/iterable/IterableDataSetTest.java   |    2 +-
 .../api/injection/scope/StateFieldTest.java     |    5 +-
 .../qi4j/api/property/PropertyErrorTest.java    |    5 +-
 .../org/qi4j/api/unitofwork/RemovalTest.java    |    7 +-
 .../qi4j/api/value/DocumentationSupport.java    |  298 +++
 .../org/qi4j/api/value/ValueCompositeTest.java  |    2 +-
 core/io/src/main/java/org/qi4j/io/Inputs.java   |   74 +
 .../qi4j/runtime/structure/ModuleInstance.java  |   41 +-
 .../value/ValueBuilderWithPrototype.java        |   40 +-
 .../org/qi4j/runtime/value/ValueInstance.java   |   28 +-
 .../java/org/qi4j/api/common/OptionalTest.java  |    6 +-
 .../org/qi4j/api/common/PropertyErrorTest.java  |    5 +-
 .../org/qi4j/api/common/PropertyTypeTest.java   |    5 +-
 .../java/org/qi4j/api/common/RemovalTest.java   |    7 +-
 .../common/UnitOfWorkCallbackEntityTest.java    |    5 +-
 .../org/qi4j/runtime/entity/AggregatedTest.java |    5 +-
 .../entity/EntityCompositeEqualityTest.java     |    6 +-
 .../qi4j/runtime/entity/EntityCreationTest.java |    5 +-
 .../org/qi4j/runtime/entity/EntityTypeTest.java |    4 +-
 .../runtime/entity/EntityVisibilityTest.java    |    8 +-
 .../java/org/qi4j/runtime/entity/QI273Test.java |    5 +-
 .../entity/associations/AssociationTest.java    |    5 +-
 .../associations/ImmutableAssociationTest.java  |    5 +-
 .../IllegalUnitOfWorkInjectionTest.java         |    4 +-
 .../injection/UnitOfWorkInjectionTest.java      |    4 +-
 .../ServiceInstantiationTests.java              |    4 +-
 .../instantiation/ValueInstantiationTests.java  |    4 +-
 .../org/qi4j/runtime/mixin/JDKMixinTest.java    |   38 +-
 .../runtime/objects/ObjectVisibilityTest.java   |   10 +-
 .../qi4j/runtime/service/ConfigurationTest.java |    5 +-
 .../runtime/service/ServiceVisibilityTest.java  |    6 +-
 .../transients/TransientVisibilityTest.java     |    6 +-
 .../runtime/types/JodaDateTimeTypeTest.java     |   41 -
 .../types/JodaLocalDateTimeTypeTest.java        |   41 -
 .../runtime/types/JodaLocalDateTypeTest.java    |   40 -
 .../org/qi4j/runtime/types/ValueLookupTest.java |   69 -
 .../qi4j/runtime/unitofwork/RemovalTest.java    |    4 +-
 .../qi4j/runtime/value/CollectionTypeTest.java  |  443 ----
 .../ValueInjectionDeserializationTest.java      |    5 +-
 .../value/ValueTypeSerializationTest.java       |  315 ---
 .../qi4j/runtime/value/ValueVisibilityTest.java |    6 +-
 .../memory/MemoryEntityStoreTest.java           |    3 +
 core/spi/build.gradle                           |    8 +-
 core/spi/src/docs/metrics.txt                   |    2 +-
 core/spi/src/docs/spi.txt                       |    9 +-
 core/spi/src/docs/valueserialization.txt        |   52 +
 .../entitystore/helpers/JSONEntityState.java    |   96 +-
 .../helpers/JSONManyAssociationState.java       |   99 +-
 .../helpers/JSONMapEntityStoreMixin.java        |   31 +-
 .../helpers/MapEntityStoreMixin.java            |   36 +-
 .../spi/value/ValueDeserializerAdapter.java     | 1042 ++++++++++
 .../qi4j/spi/value/ValueSerializerAdapter.java  |  519 +++++
 .../main/java/org/qi4j/spi/value/package.html   |    5 +
 .../orgjson/OrgJsonValueDeserializer.java       |  452 +++++
 .../orgjson/OrgJsonValueSerialization.java      |  144 ++
 .../OrgJsonValueSerializationService.java       |   28 +
 .../orgjson/OrgJsonValueSerializer.java         |  112 ++
 .../valueserialization/orgjson/package.html     |    5 +
 .../helpers/JSONManyAssociationStateTest.java   |  137 ++
 core/spi/src/test/resources/logback-test.xml    |   16 +
 .../java/org/qi4j/test/EntityTestAssembler.java |    4 +-
 .../java/org/qi4j/test/util/JSONAssert.java     |   63 +-
 .../AbstractCollectionSerializationTest.java    |  416 ++++
 .../test/value/AbstractJsonDateFormatTest.java  |   88 +
 .../AbstractPlainValueSerializationTest.java    |  208 ++
 ...AbstractValueCompositeSerializationTest.java |  408 ++++
 .../main/java/org/qi4j/test/value/package.html  |    5 +
 .../org/qi4j/cache/ehcache/EhCacheTest.java     |    6 +-
 extensions/entitystore-file/build.gradle        |   17 +-
 .../file/assembly/FileEntityStoreAssembler.java |    6 +
 .../entitystore/file/FileEntityStoreTest.java   |   14 +-
 .../qi4j/entitystore/gae/GaeEntityState.java    |   57 +-
 .../entitystore/gae/GaeEntityStoreMixin.java    |   19 +-
 .../gae/GaeEntityStoreUnitOfWork.java           |   27 +-
 extensions/entitystore-hazelcast/build.gradle   |   22 +-
 .../assembly/HazelcastEntityStoreAssembler.java |   10 +-
 .../hazelcast/HazelcastEntityStoreTest.java     |   17 +-
 extensions/entitystore-jclouds/build.gradle     |   19 +-
 .../jclouds/JCloudsMapEntityStoreAssembler.java |   14 +-
 .../jclouds/JCloudsFilesystemTest.java          |   11 +-
 .../jclouds/JCloudsTransientTest.java           |    6 +-
 extensions/entitystore-jdbm/build.gradle        |    1 +
 .../jdbm/assembly/JdbmEntityStoreAssembler.java |   25 +-
 .../entitystore/jdbm/JdbmEntityStoreTest.java   |   93 +-
 extensions/entitystore-leveldb/build.gradle     |    1 +
 .../leveldb/LevelDBEntityStoreAssembler.java    |    1 -
 .../leveldb/JavaLevelDBEntityStoreTest.java     |    4 +-
 .../leveldb/JniLevelDBEntityStoreTest.java      |    3 +-
 extensions/entitystore-mongodb/build.gradle     |    3 +
 .../mongodb/MongoEntityStoreConfiguration.java  |    2 +-
 .../mongodb/MongoMapEntityStoreAssembler.java   |   39 +-
 .../mongodb/MongoMapEntityStoreMixin.java       |   11 -
 .../mongodb/MongoMapEntityStoreTest.java        |   14 +-
 extensions/entitystore-neo4j/build.gradle       |    1 +
 .../qi4j/entitystore/neo4j/NeoEntityState.java  |  100 +-
 .../entitystore/neo4j/NeoEntityStoreMixin.java  |   11 +-
 .../neo4j/NeoEntityStoreUnitOfWork.java         |    9 +-
 .../neo4j/test/SimpleNeoStoreTest.java          |   40 +-
 extensions/entitystore-preferences/build.gradle |   11 +-
 .../prefs/PreferencesEntityStoreMixin.java      |   62 +-
 .../PreferenceEntityStoreAssembler.java         |    1 +
 .../entitystore/PreferencesEntityStoreTest.java |   11 +-
 extensions/entitystore-redis/build.gradle       |   15 +-
 .../redis/RedisMapEntityStoreAssembler.java     |    1 -
 .../redis/RedisMapEntityStoreTest.java          |   23 +-
 extensions/entitystore-riak/build.gradle        |   19 +-
 .../riak/RiakHttpMapEntityStoreAssembler.java   |    1 -
 .../RiakProtobufMapEntityStoreAssembler.java    |    1 -
 .../riak/RiakHttpMapEntityStoreTest.java        |   20 +-
 .../riak/RiakProtobufMapEntityStoreTest.java    |   20 +-
 extensions/entitystore-sql/build.gradle         |    1 +
 .../entitystore/sql/SQLEntityStoreMixin.java    |   33 +-
 .../AbstractSQLEntityStoreAssembler.java        |   58 +-
 .../sql/DerbySQLEntityStoreTest.java            |    6 +-
 .../entitystore/sql/H2SQLEntityStoreTest.java   |    6 +-
 .../entitystore/sql/MySQLEntityStoreTest.java   |    6 +-
 .../sql/PostgreSQLEntityStoreTest.java          |    6 +-
 .../entitystore/sql/SQLiteEntityStoreTest.java  |    6 +-
 extensions/entitystore-voldemort/build.gradle   |   40 +-
 .../voldemort/assembly/VoldemortAssembler.java  |    9 +-
 .../entitystore/voldemort/VoldemortTest.java    |   17 +-
 .../elasticsearch/ElasticSearchIndexer.java     |  210 +-
 .../assembly/ESClusterIndexQueryAssembler.java  |    5 +
 .../ESFilesystemIndexQueryAssembler.java        |    5 +
 .../assembly/ESMemoryIndexQueryAssembler.java   |    5 +
 .../ElasticSearchComplexQueryTest.java          |    4 +-
 .../elasticsearch/ElasticSearchFinderTest.java  |    4 +-
 .../elasticsearch/ElasticSearchQueryTest.java   |    4 +-
 .../index/elasticsearch/ElasticSearchTest.java  |    3 +-
 .../src/test/resources/logback-test.xml         |   16 +
 extensions/indexing-rdf/build.gradle            |   21 +-
 .../rdf/assembly/RdfMemoryStoreAssembler.java   |    3 +
 .../assembly/RdfNativeSesameStoreAssembler.java |    3 +
 .../assembly/RdfRdbmsSesameStoreAssembler.java  |    3 +
 .../index/rdf/query/RdfQueryParserFactory.java  |    9 +-
 .../rdf/query/internal/RdfQueryParserImpl2.java |  155 +-
 .../org/qi4j/index/rdf/ContainsAllTest.java     |    3 +-
 .../java/org/qi4j/index/rdf/ContainsTest.java   |   51 +-
 .../org/qi4j/index/rdf/RDFPerformanceTest.java  |    3 +-
 .../org/qi4j/index/rdf/RdfComplexQueryTest.java |    5 +-
 .../org/qi4j/index/rdf/RdfEntityFinderTest.java |    3 +
 .../org/qi4j/index/rdf/RdfNamedQueryTest.java   |    3 +
 .../java/org/qi4j/index/rdf/RdfQueryTest.java   |    7 +-
 .../qi4j/index/rdf/qi64/AbstractIssueTest.java  |    8 +-
 .../org/qi4j/index/rdf/qi66/Qi66IssueTest.java  |    6 +-
 .../org/qi4j/index/rdf/qi95/Qi95IssueTest.java  |   13 +-
 .../java/org/qi4j/index/solr/SolrAssembler.java |    4 +-
 .../index/sql/postgresql/SQLTestHelper.java     |    8 +-
 .../metrics/yammer/NoMetricsInstalledTest.java  |    4 +-
 .../org/qi4j/metrics/yammer/YammerTest.java     |   10 +-
 .../org/qi4j/index/reindexer/ReindexerTest.java |    4 +-
 .../valueserialization-jackson/build.gradle     |   17 +
 .../valueserialization-jackson/dev-status.xml   |   17 +
 .../src/docs/vs-jackson.txt                     |   24 +
 .../jackson/JacksonValueDeserializer.java       |  348 ++++
 .../JacksonValueSerializationAssembler.java     |   67 +
 .../JacksonValueSerializationService.java       |   28 +
 .../jackson/JacksonValueSerializer.java         |   88 +
 .../valueserialization/jackson/package.html     |    5 +
 .../JacksonCollectionSerializationTest.java     |   33 +
 .../jackson/JacksonJsonDateFormatTest.java      |   33 +
 .../JacksonPlainValueSerializationTest.java     |   34 +
 .../JacksonValueCompositeSerializationTest.java |   33 +
 .../src/test/resources/logback-test.xml         |   18 +
 .../valueserialization-orgjson/build.gradle     |   15 +
 .../valueserialization-orgjson/dev-status.xml   |   17 +
 .../src/docs/vs-orgjson.txt                     |   24 +
 .../OrgJsonValueSerializationAssembler.java     |   67 +
 .../valueserialization/orgjson/package.html     |    5 +
 .../OrgJsonCollectionSerializationTest.java     |   33 +
 .../orgjson/OrgJsonDateFormatTest.java          |   33 +
 .../OrgJsonPlainValueSerializationTest.java     |   34 +
 .../OrgJsonValueCompositeSerializationTest.java |   33 +
 extensions/valueserialization-stax/build.gradle |   16 +
 .../valueserialization-stax/dev-status.xml      |   17 +
 .../src/docs/vs-stax.txt                        |   24 +
 .../stax/StaxValueDeserializer.java             |  463 +++++
 .../stax/StaxValueSerializationAssembler.java   |   67 +
 .../stax/StaxValueSerializationService.java     |   28 +
 .../stax/StaxValueSerializer.java               |  130 ++
 .../qi4j/valueserialization/stax/package.html   |    5 +
 .../stax/StaxCollectionSerializationTest.java   |   33 +
 .../stax/StaxPlainValueSerializationTest.java   |   34 +
 .../StaxValueCompositeSerializationTest.java    |   33 +
 .../src/test/resources/logback-test.xml         |   19 +
 libraries.gradle                                |    4 +
 .../library/alarm/AlarmHistoryImplTest.java     |    6 +-
 .../qi4j/library/alarm/AlarmPointImplTest.java  |    6 +-
 .../org/qi4j/library/alarm/AlarmProxyTest.java  |    6 +-
 .../qi4j/library/alarm/AlarmServiceTest.java    |    6 +-
 .../library/alarm/ExtendedAlarmModelTest.java   |    8 +-
 .../library/alarm/SimpleAlarmModelTest.java     |    6 +-
 .../library/alarm/StandardAlarmModelTest.java   |    6 +-
 .../conversion/values/EntityToValueTest.java    |    4 +-
 libraries/eventsourcing-jdbm/build.gradle       |    1 +
 .../source/jdbm/JdbmEventStoreService.java      |   46 +-
 .../source/jdbm/JdbmEventStoreServiceTest.java  |   13 +-
 .../replay/ApplicationEventPlayerService.java   |    3 +-
 .../domain/replay/DomainEventPlayerService.java |    3 +-
 .../domain/source/AbstractEventStoreMixin.java  |    5 -
 .../library/http/JettyJMXStatisticsTest.java    |    4 +-
 .../org/qi4j/library/http/JettyServiceTest.java |    4 +-
 .../http/MutualSecureJettyServiceTest.java      |    4 +-
 .../library/http/SecureJettyServiceTest.java    |    4 +-
 .../http/VirtualHostJettyServiceTest.java       |    4 +-
 .../java/org/qi4j/logging/DebuggingTest.java    |    4 +-
 .../test/java/org/qi4j/logging/TracingTest.java |    6 +-
 libraries/rdf/build.gradle                      |    1 +
 .../rdf/entity/EntityStateSerializer.java       |   59 +-
 .../rdf/entity/EntitySerializerTest.java        |    9 +-
 .../rdf/entity/EntityTypeSerializerTest.java    |    4 +-
 .../rdf/repository/NativeRepositoryTest.java    |    4 +-
 libraries/rest-client/build.gradle              |   17 +-
 .../ValueCompositeRequestWriter.java            |   43 +-
 .../responsereader/JSONResponseReader.java      |   19 +-
 .../ContextResourceClientFactoryTest.java       |   18 +-
 .../rest/client/ContinuousIntegrationTest.java  |    7 +-
 .../qi4j/library/rest/client/RssReaderTest.java |    3 +-
 .../requestreader/DefaultRequestReader.java     |   22 +-
 .../ValueCompositeResponseWriter.java           |   10 +-
 .../ValueDescriptorResponseWriter.java          |    2 +-
 libraries/rest/build.gradle                     |   27 +-
 .../library/rest/admin/EntitiesResource.java    |   60 +-
 .../qi4j/library/rest/admin/EntityResource.java |  264 +--
 .../library/rest/admin/RestApplication.java     |    4 +-
 .../qi4j/library/rest/admin/RDFAssembler.java   |    2 +
 .../org/qi4j/library/rest/admin/RestTest.java   |  159 +-
 .../rest/admin/RestletApplicationAssembler.java |   36 -
 .../library/shiro/web/WebHttpShiroTest.java     |    4 +-
 .../library/shiro/web/WebRealmServiceTest.java  |    4 +-
 libraries/sql-liquibase/build.gradle            |    3 +-
 .../sql/liquibase/LiquibaseServiceTest.java     |    4 +-
 ...taSourceConfigurationManagerServiceTest.java |    6 +-
 manual/src/docs/userguide/extensions.txt        |   13 +
 samples/dci-cargo/dcisample_a/build.gradle      |    1 +
 .../sample_a/bootstrap/assembly/Assembler.java  |   26 +-
 .../data/shipping/cargo/RouteSpecification.java |    5 +-
 .../data/shipping/delivery/Delivery.java        |    7 +-
 .../delivery/ExpectedHandlingEvent.java         |    5 +-
 .../sample_a/data/shipping/itinerary/Leg.java   |    7 +-
 .../data/shipping/voyage/CarrierMovement.java   |    5 +-
 .../infrastructure/model/JSONModel.java         |   18 +-
 .../sample_a/bootstrap/test/TestAssembler.java  |   20 +-
 samples/dci-cargo/dcisample_b/build.gradle      |    1 +
 .../sample_b/bootstrap/assembly/Assembler.java  |   25 +-
 .../structure/cargo/RouteSpecification.java     |    5 +-
 .../data/structure/delivery/Delivery.java       |    3 +-
 .../structure/delivery/NextHandlingEvent.java   |    5 +-
 .../sample_b/data/structure/itinerary/Leg.java  |   15 +-
 .../infrastructure/model/JSONModel.java         |   18 +-
 .../bootstrap/test/TestApplication.java         |    7 +
 .../sample_b/bootstrap/test/TestAssembler.java  |   26 +-
 .../context/test/booking/BookNewCargoTest.java  |   27 +-
 .../moneytransfer/test/TransferMoneyTest.java   |    7 +-
 .../moneytransfer/test/TransferMoneyTest2.java  |    7 +-
 .../qi4j/samples/forum/data/entity/User.java    |    2 +-
 settings.gradle                                 |    3 +
 tests/performance/build.gradle                  |   27 +-
 .../MemoryEntityStorePerformanceTest.java       |    5 +
 .../tests/regression/qi328/Qi328TestCase.java   |    6 +-
 .../tutorials/services/step4/LibraryTest.java   |    6 +-
 .../tutorials/services/step5/LibraryTest.java   |    6 +-
 .../tutorials/services/step6/LibraryTest.java   |    6 +-
 293 files changed, 8583 insertions(+), 8082 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
----------------------------------------------------------------------
diff --cc core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
index d51fd0e,06831bc..50ab2a4
--- a/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
+++ b/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
@@@ -457,8 -457,7 +457,7 @@@ public final class PropertyMappe
          @Override
          public Object map( Composite composite, Type type, String value )
          {
-             return Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF
-                 .map( composite ).module().newValueFromJSON( (Class<Object>) type, value );
 -            return Qi4j.INSTANCE_FUNCTION.map( composite ).module().newValueFromSerializedState( (Class<Object>) type, value );
++            return Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( composite ).module().newValueFromSerializedState( (Class<Object>) type, value );
          }
      }
  

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/api/src/main/java/org/qi4j/api/type/MapType.java
----------------------------------------------------------------------
diff --cc core/api/src/main/java/org/qi4j/api/type/MapType.java
index 047b3ae,546fada..c90690f
--- a/core/api/src/main/java/org/qi4j/api/type/MapType.java
+++ b/core/api/src/main/java/org/qi4j/api/type/MapType.java
@@@ -34,14 -33,23 +33,23 @@@ public final class MapTyp
          return Map.class.isAssignableFrom( cl );
      }
  
+     public static MapType of( Class<?> keyType, Class<?> valueType )
+     {
+         return new MapType( Map.class, ValueType.of( keyType ), ValueType.of( valueType ) );
+     }
+ 
      public MapType( Class<?> type, ValueType keyType, ValueType valueType )
      {
-         super( Iterables.iterable( type ) );
+         super( type );
          this.keyType = keyType;
          this.valueType = valueType;
+         if( !isMap( type ) )
+         {
+             throw new IllegalArgumentException( type + " is not a Map." );
+         }
      }
  
 -    public ValueType getKeyType()
 +    public ValueType keyType()
      {
          return keyType;
      }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithPrototype.java
----------------------------------------------------------------------
diff --cc core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithPrototype.java
index fe9ef6b,34a8b43..0608ace
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithPrototype.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithPrototype.java
@@@ -27,19 -46,16 +46,16 @@@ public class ValueBuilderWithPrototype<
          try
          {
              // @TODO there is probably a more efficient way to do this
-             JSONObjectSerializer serializer = new JSONObjectSerializer();
-             serializer.serialize(prototype, valueModel.valueType());
-             Object object = serializer.rootObject();
- 
-             JSONDeserializer deserializer = new JSONDeserializer( currentModule );
-             value = deserializer.deserialize(object, valueModel.valueType());
+             ValueSerialization valueSerialization = currentModule.valueSerialization();
+             String serialized = valueSerialization.serialize( prototype );
+             value = valueSerialization.deserialize( valueModel.valueType(), serialized);
          }
-         catch( JSONException e )
+         catch( ValueSerializationException e )
          {
-             throw new IllegalStateException( "Could not JSON-copy Value", e );
+             throw new IllegalStateException( "Could not serialize-copy Value", e );
          }
  
 -        ValueInstance valueInstance = ValueInstance.getValueInstance( (ValueComposite) value );
 +        ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value );
          valueInstance.prepareToBuild();
          this.prototypeInstance = valueInstance;
      }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
----------------------------------------------------------------------
diff --cc core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
index 558eadf,8ad7a37..a68d108
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueInstance.java
@@@ -33,10 -30,12 +30,11 @@@ import org.qi4j.runtime.structure.Modul
  /**
   * ValueComposite instance
   */
- public final class ValueInstance extends TransientInstance
+ public final class ValueInstance
+     extends TransientInstance
      implements CompositeInstance, MixinsInstance
  {
 -
 -    public static ValueInstance getValueInstance( ValueComposite composite )
 +    public static ValueInstance valueInstanceOf( ValueComposite composite )
      {
          return (ValueInstance) Proxy.getInvocationHandler( composite );
      }
@@@ -144,15 -142,6 +141,6 @@@
      @Override
      public String toString()
      {
-         StringWriter string = new StringWriter();
-         try
-         {
-             new JSONWriterSerializer( string ).serialize( this.<ValueComposite>proxy() );
-         }
-         catch( JSONException e )
-         {
-             throw new IllegalStateException( "Could not JSON serialize value", e );
-         }
-         return string.toString();
+         return module().valueSerialization().serialize( this.<ValueComposite>proxy() );
      }
--}
++}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/spi/src/docs/spi.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONEntityState.java
----------------------------------------------------------------------
diff --cc core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONEntityState.java
index 33ef878,5d61190..aed4d7d
--- a/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONEntityState.java
+++ b/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONEntityState.java
@@@ -128,9 -136,7 +136,7 @@@ public final class JSONEntityStat
              }
              else
              {
-                 Module module = unitOfWork.module();
 -                PropertyDescriptor descriptor = entityDescriptor.state().getPropertyByQualifiedName( stateName );
 +                PropertyDescriptor descriptor = entityDescriptor.state().findPropertyModelByQualifiedName( stateName );
- 
                  if( descriptor == null )
                  {
                      return null;
@@@ -315,4 -333,4 +333,4 @@@
              throw new EntityStoreException( e );
          }
      }
--}
++}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONMapEntityStoreMixin.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/MapEntityStoreMixin.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java
----------------------------------------------------------------------
diff --cc core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java
index 0000000,f27dd5b..e5285fc
mode 000000,100644..100644
--- a/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java
+++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java
@@@ -1,0 -1,1042 +1,1042 @@@
+ /*
+  * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+  * Copyright (c) 2010, Niclas Hehdman. All Rights Reserved.
+  * Copyright (c) 2012, Paul Merlin. All Rights Reserved.
+  *
+  * Licensed 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.qi4j.spi.value;
+ 
+ import java.io.ByteArrayInputStream;
+ import java.io.InputStream;
+ import java.io.ObjectInputStream;
+ import java.math.BigDecimal;
+ import java.math.BigInteger;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Date;
+ 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 org.joda.time.DateTime;
+ import org.joda.time.DateTimeZone;
+ import org.joda.time.LocalDate;
+ import org.joda.time.LocalDateTime;
+ import org.qi4j.api.association.AssociationDescriptor;
+ import org.qi4j.api.entity.EntityReference;
+ import org.qi4j.api.injection.scope.Service;
+ import org.qi4j.api.injection.scope.Structure;
+ import org.qi4j.api.property.PropertyDescriptor;
+ import org.qi4j.api.service.ServiceReference;
+ import org.qi4j.api.structure.Application;
+ import org.qi4j.api.structure.Module;
+ import org.qi4j.api.type.CollectionType;
+ import org.qi4j.api.type.EnumType;
+ import org.qi4j.api.type.MapType;
+ import org.qi4j.api.type.ValueCompositeType;
+ import org.qi4j.api.type.ValueType;
+ import org.qi4j.api.util.Base64Encoder;
+ import org.qi4j.api.util.Dates;
+ import org.qi4j.api.value.ValueBuilder;
+ import org.qi4j.api.value.ValueDescriptor;
+ import org.qi4j.api.value.ValueDeserializer;
+ import org.qi4j.api.value.ValueSerializationException;
+ import org.qi4j.functional.Function;
+ import org.qi4j.functional.Function2;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import static org.qi4j.functional.Iterables.*;
+ 
+ /**
+  * 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>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>
+  *
+  * @param <InputType> Implementor pull-parser type
+  * @param <InputNodeType> Implementor tree-parser node type
+  */
+ public abstract class ValueDeserializerAdapter<InputType, InputNodeType>
+     implements ValueDeserializer
+ {
+ 
+     private static final Logger LOG = LoggerFactory.getLogger( ValueDeserializerAdapter.class );
+     private static final Logger PULL_PARSING_LOG = LoggerFactory.getLogger( ValueDeserializerAdapter.class.getName() + "#PullParsing" );
+     private static final Logger TREE_PARSING_LOG = LoggerFactory.getLogger( ValueDeserializerAdapter.class.getName() + "#TreeParsing" );
+     private static final String UTF_8 = "UTF-8";
+     private final Map<Class<?>, Function<Object, Object>> deserializers = new HashMap<Class<?>, Function<Object, Object>>();
+     private final Application application;
+     private final Module module;
+     private Function<Application, Module> valuesModuleFinder;
+     private Module valuesModule;
+ 
+     /**
+      * 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( "unchecked" )
+     public ValueDeserializerAdapter( @Structure Application application,
+                                      @Structure Module module,
+                                      @Service ServiceReference<ValueDeserializer> serviceRef )
+     {
+         this( application, module, serviceRef.metaInfo( Function.class ) );
+     }
+ 
+     protected ValueDeserializerAdapter( Application application,
+                                         Module module,
+                                         Function<Application, Module> valuesModuleFinder )
+     {
+ 
+         this.application = application;
+         this.module = module;
+         setValuesModuleFinder( valuesModuleFinder );
+ 
+         // Primitive Value types
+         registerDeserializer( String.class, new Function<Object, String>()
+         {
+             @Override
+             public String map( Object input )
+             {
+                 return input.toString();
+             }
+         } );
+         registerDeserializer( Boolean.class, new Function<Object, Boolean>()
+         {
+             @Override
+             public Boolean map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Boolean.parseBoolean( (String) input )
+                        : ( (Boolean) input ).booleanValue();
+             }
+         } );
+         registerDeserializer( Integer.class, new Function<Object, Integer>()
+         {
+             @Override
+             public Integer map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Integer.parseInt( (String) input )
+                        : ( (Number) input ).intValue();
+             }
+         } );
+         registerDeserializer( Long.class, new Function<Object, Long>()
+         {
+             @Override
+             public Long map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Long.parseLong( (String) input )
+                        : ( (Number) input ).longValue();
+             }
+         } );
+         registerDeserializer( Short.class, new Function<Object, Short>()
+         {
+             @Override
+             public Short map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Short.parseShort( (String) input )
+                        : ( (Number) input ).shortValue();
+             }
+         } );
+         registerDeserializer( Byte.class, new Function<Object, Byte>()
+         {
+             @Override
+             public Byte map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Byte.parseByte( (String) input )
+                        : ( (Number) input ).byteValue();
+             }
+         } );
+         registerDeserializer( Float.class, new Function<Object, Float>()
+         {
+             @Override
+             public Float map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Float.parseFloat( (String) input )
+                        : ( (Number) input ).floatValue();
+             }
+         } );
+         registerDeserializer( Double.class, new Function<Object, Double>()
+         {
+             @Override
+             public Double map( Object input )
+             {
+                 return ( input instanceof String )
+                        ? Double.parseDouble( (String) input )
+                        : ( (Number) input ).doubleValue();
+             }
+         } );
+ 
+         // Number types
+         registerDeserializer( BigDecimal.class, new Function<Object, BigDecimal>()
+         {
+             @Override
+             public BigDecimal map( Object input )
+             {
+                 return new BigDecimal( input.toString() );
+             }
+         } );
+         registerDeserializer( BigInteger.class, new Function<Object, BigInteger>()
+         {
+             @Override
+             public BigInteger map( Object input )
+             {
+                 return new BigInteger( input.toString() );
+             }
+         } );
+ 
+         // Date types
+         registerDeserializer( Date.class, new Function<Object, Date>()
+         {
+             @Override
+             public Date map( Object input )
+             {
+                 return Dates.fromString( input.toString() );
+             }
+         } );
+         registerDeserializer( DateTime.class, new Function<Object, DateTime>()
+         {
+             @Override
+             public DateTime map( Object input )
+             {
+                 return new DateTime( input, DateTimeZone.UTC );
+             }
+         } );
+         registerDeserializer( LocalDateTime.class, new Function<Object, LocalDateTime>()
+         {
+             @Override
+             public LocalDateTime map( Object input )
+             {
+                 return new LocalDateTime( input );
+             }
+         } );
+         registerDeserializer( LocalDate.class, new Function<Object, LocalDate>()
+         {
+             @Override
+             public LocalDate map( Object input )
+             {
+                 return new LocalDate( input );
+             }
+         } );
+ 
+         // Other supported types
+         registerDeserializer( EntityReference.class, new Function<Object, EntityReference>()
+         {
+             @Override
+             public EntityReference map( Object input )
+             {
+                 return EntityReference.parseEntityReference( input.toString() );
+             }
+         } );
+     }
+ 
+     private void setValuesModuleFinder( Function<Application, Module> valuesModuleFinder )
+     {
+         if( valuesModuleFinder != null )
+         {
+             LOG.debug( "Will use the provided Function to find Module to build new ValueComposites instances: {}",
+                        valuesModuleFinder );
+         }
+         this.valuesModuleFinder = valuesModuleFinder;
+         this.valuesModule = null;
+     }
+ 
+     private Module valuesModule()
+     {
+         if( valuesModule == null )
+         {
+             if( valuesModuleFinder == null )
+             {
+                 valuesModule = module;
+             }
+             else
+             {
+                 valuesModule = valuesModuleFinder.map( application );
+                 if( valuesModule == null )
+                 {
+                     throw new ValueSerializationException( "Values Module provided by the finder Function was null." );
+                 }
+                 LOG.debug( "Will use a specific Module to build new ValueComposites instances: {}", valuesModule );
+             }
+         }
+         return valuesModule;
+     }
+ 
+     @Override
+     public <T> Function<String, T> deserialize( Class<T> type )
+     {
+         if( CollectionType.isCollection( type ) )
+         {
+             ValueType objectValueType = new ValueType( Object.class );
+             return deserialize( new CollectionType( type, objectValueType ) );
+         }
+         if( MapType.isMap( type ) )
+         {
+             ValueType objectValueType = new ValueType( Object.class );
+             return deserialize( new MapType( type, objectValueType, objectValueType ) );
+         }
+         return deserialize( new ValueType( type ) );
+     }
+ 
+     @Override
+     public final <T> Function<String, T> deserialize( final ValueType valueType )
+     {
+         return new Function<String, T>()
+         {
+             @Override
+             public T map( String input )
+             {
+                 return deserialize( valueType, input );
+             }
+         };
+     }
+ 
+     @Override
+     public final <T> Function2<ValueType, String, T> deserialize()
+     {
+         return new Function2<ValueType, String, T>()
+         {
+             @Override
+             public T map( ValueType valueType, String input )
+             {
+                 return deserialize( valueType, input );
+             }
+         };
+     }
+ 
+     @Override
+     public final <T> T deserialize( Class<?> type, String input )
+         throws ValueSerializationException
+     {
+         if( CollectionType.isCollection( type ) )
+         {
+             ValueType objectValueType = new ValueType( Object.class );
+             return deserialize( new CollectionType( type, objectValueType ), input );
+         }
+         if( MapType.isMap( type ) )
+         {
+             ValueType objectValueType = new ValueType( Object.class );
+             return deserialize( new MapType( type, objectValueType, objectValueType ), input );
+         }
+         return deserialize( new ValueType( type ), input );
+     }
+ 
+     @Override
+     public final <T> T deserialize( ValueType valueType, String input )
+         throws ValueSerializationException
+     {
+         try
+         {
+             return deserializeRoot( 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( Class<?> type, InputStream input )
+         throws ValueSerializationException
+     {
+         if( CollectionType.isCollection( type ) )
+         {
+             ValueType objectValueType = new ValueType( Object.class );
+             return deserialize( new CollectionType( type, objectValueType ), input );
+         }
+         if( MapType.isMap( type ) )
+         {
+             ValueType objectValueType = new ValueType( Object.class );
+             return deserialize( new MapType( type, objectValueType, objectValueType ), input );
+         }
+         return deserialize( new ValueType( type ), input );
+     }
+ 
+     @Override
+     public final <T> T deserialize( ValueType valueType, InputStream input )
+         throws ValueSerializationException
+     {
+         try
+         {
+             return deserializeRoot( valueType, input );
+         }
+         catch( ValueSerializationException ex )
+         {
+             throw ex;
+         }
+         catch( Exception ex )
+         {
+             throw new ValueSerializationException( "Could not deserialize value", ex );
+         }
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T deserializeRoot( ValueType valueType, InputStream input )
+         throws Exception
+     {
+         final Class<?> type = first( valueType.types() );
+         // Plain ValueType
+         if( deserializers.get( type ) != 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) deserializers.get( type ).map( 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( string );
+         }
+         else // Complex ValueType
+         {
+             InputType adaptedInput = adaptInput( input );
+             onDeserializationStart( valueType, adaptedInput );
+             T deserialized = doDeserialize( valueType, adaptedInput );
+             onDeserializationEnd( valueType, adaptedInput );
+             return deserialized;
+         }
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T doDeserialize( ValueType valueType, InputType input )
+         throws Exception
+     {
+         final Class<?> type = first( valueType.types() );
+         // Registered deserializers
+         if( deserializers.get( type ) != null )
+         {
+             Object value = readPlainValue( input );
+             if( value == null )
+             {
+                 return null;
+             }
+             return (T) deserializers.get( type ).map( value );
+         }
+         else // Explicit ValueComposite
+         if( ValueCompositeType.class.isAssignableFrom( valueType.getClass() ) )
+         {
+             PULL_PARSING_LOG.trace( "ValueCompositeType assignable - deserializeValueComposite( {} )", input );
+             return (T) deserializeValueComposite( valueType, input );
+         }
+         else // Explicit Collections
+         if( CollectionType.class.isAssignableFrom( valueType.getClass() ) )
+         {
+             PULL_PARSING_LOG.trace( "CollectionType assignable - deserializeCollection( {} )", input );
+             return (T) deserializeCollection( (CollectionType) valueType, input );
+         }
+         else // Explicit Map
+         if( MapType.class.isAssignableFrom( valueType.getClass() ) )
+         {
+             PULL_PARSING_LOG.trace( "MapType assignable - deserializeMap( {} )", input );
+             return (T) deserializeMap( (MapType) valueType, input );
+         }
+         else // Enum
+         if( EnumType.class.isAssignableFrom( valueType.getClass() ) || type.isEnum() )
+         {
+             PULL_PARSING_LOG.trace( "EnumType assignable - readValue( {} )", input );
+             return (T) Enum.valueOf( (Class) type, readPlainValue( input ).toString() );
+         }
+         else // Array
+         if( type.isArray() )
+         {
+             return (T) deserializeBase64Serialized( readPlainValue( input ).toString() );
+         }
+         // Guessed Deserialization
+         PULL_PARSING_LOG.trace( "Unknown ValueType - deserializeGuessed( {} )", input );
+         return (T) deserializeGuessed( valueType, input );
+     }
+ 
+     private <T> Function<InputType, T> buildDeserializeInputFunction( final ValueType valueType )
+     {
+         return new Function<InputType, T>()
+         {
+             @Override
+             public T map( InputType input )
+             {
+                 try
+                 {
+                     return doDeserialize( valueType, input );
+                 }
+                 catch( ValueSerializationException ex )
+                 {
+                     throw ex;
+                 }
+                 catch( Exception ex )
+                 {
+                     throw new ValueSerializationException( ex );
+                 }
+             }
+         };
+     }
+ 
+     private <T> Collection<T> deserializeCollection( CollectionType collectionType, InputType input )
+         throws Exception
+     {
+         Collection<T> collection;
+         Class<?> collectionMainType = first( collectionType.types() );
+         if( Set.class.equals( collectionMainType ) )
+         {
+             collection = new LinkedHashSet<T>();
+         }
+         else
+         {
+             collection = new ArrayList<T>();
+         }
+         return readArrayInCollection( input,
+                                       this.<T>buildDeserializeInputFunction( collectionType.collectedType() ),
+                                       collection );
+     }
+ 
+     private <K, V> Map<K, V> deserializeMap( MapType mapType, InputType input )
+         throws Exception
+     {
+         return readMapInMap( input,
 -                             this.<K>buildDeserializeInputFunction( mapType.getKeyType() ),
 -                             this.<V>buildDeserializeInputFunction( mapType.getValueType() ),
++                             this.<K>buildDeserializeInputFunction( mapType.keyType() ),
++                             this.<V>buildDeserializeInputFunction( mapType.valueType() ),
+                              new HashMap<K, V>() );
+     }
+ 
+     private <T> T deserializeValueComposite( ValueType valueType, InputType input )
+         throws Exception
+     {
+         PULL_PARSING_LOG.trace( "Switching to TREE PARSING @( {} )", input );
+         InputNodeType inputNode = readObjectTree( input );
+         TREE_PARSING_LOG.trace( "Switched to TREE PARSING @( {} )", input );
+         TREE_PARSING_LOG.trace( "ObjectNode is {}", inputNode );
+         if( inputNode == null )
+         {
+             return null;
+         }
+         return deserializeNodeValueComposite( valueType, inputNode );
+     }
+ 
+     private <T> T deserializeNodeValueComposite( ValueType valueType, InputNodeType inputNode )
+         throws Exception
+     {
+         ValueCompositeType valueCompositeType = (ValueCompositeType) valueType;
+         Class<?> valueBuilderType = first( valueCompositeType.types() );
+         String typeInfo = this.<String>getObjectFieldValue(
+             inputNode,
+             "_type",
+             this.<String>buildDeserializeInputNodeFunction( new ValueType( String.class ) ) );
+         TREE_PARSING_LOG.trace(
+             "In deserializeNodeValueComposite(), getObjectFieldValue( {} ) returned '{}'",
+             inputNode, typeInfo );
+         if( typeInfo != null )
+         {
+             ValueDescriptor valueDescriptor = valuesModule().valueDescriptor( typeInfo );
+             if( valueDescriptor == null )
+             {
+                 throw new ValueSerializationException( "Specified value type could not be resolved: " + typeInfo );
+             }
+             valueCompositeType = valueDescriptor.valueType();
+             valueBuilderType = Class.forName( typeInfo );
+             if( !valueType.equals( valueCompositeType ) )
+             {
+                 TREE_PARSING_LOG.debug(
+                     "Overriding {} with {} as defined in _type field.",
+                     valueType, valueCompositeType );
+             }
+         }
+         return deserializeValueComposite( valueCompositeType, valueBuilderType, inputNode );
+     }
+ 
+     private <T> T deserializeValueComposite( ValueCompositeType valueCompositeType, Class<?> valueBuilderType, InputNodeType inputNode )
+         throws Exception
+     {
+         final Map<String, Object> stateMap = new HashMap<String, Object>();
+ 
+         // Properties
+         for( PropertyDescriptor property : valueCompositeType.properties() )
+         {
+             String propertyName = property.qualifiedName().name();
+             Object value;
+             if( objectHasField( inputNode, propertyName ) )
+             {
+                 value = getObjectFieldValue(
+                     inputNode,
+                     propertyName,
+                     buildDeserializeInputNodeFunction( property.valueType() ) );
+                 TREE_PARSING_LOG.trace(
+                     "In deserializeValueComposite(), getObjectFieldValue( {} ) for key {} returned '{}' of class {}",
+                     inputNode, propertyName, value, value == null ? "N/A" : value.getClass() );
+                 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 );
+                     }
+                 }
+                 TREE_PARSING_LOG.trace( "Property {}#{}( {} ) deserialized value is '{}' of class {}",
+                                         property.qualifiedName().type(),
+                                         property.qualifiedName().name(),
+                                         property.valueType(),
+                                         value,
+                                         value == null ? "N/A" : value.getClass() );
+             }
+             else
+             {
+                 // Serialized object does not contain the field, try to default it
+                 value = property.initialValue( valuesModule() );
+                 TREE_PARSING_LOG.trace(
+                     "Property {} was not defined in serialized object and has been defaulted to '{}'",
+                     property.qualifiedName(), value );
+             }
+             stateMap.put( propertyName, value );
+         }
+ 
+         // Associations
+         for( AssociationDescriptor association : valueCompositeType.associations() )
+         {
+             String associationName = association.qualifiedName().name();
+             if( objectHasField( inputNode, associationName ) )
+             {
+                 Object value = getObjectFieldValue(
+                     inputNode,
+                     associationName,
+                     buildDeserializeInputNodeFunction( new ValueType( EntityReference.class ) ) );
+                 stateMap.put( associationName, value );
+             }
+         }
+ 
+         // ManyAssociations
+         for( AssociationDescriptor manyAssociation : valueCompositeType.manyAssociations() )
+         {
+             String manyAssociationName = manyAssociation.qualifiedName().name();
+             if( objectHasField( inputNode, manyAssociationName ) )
+             {
+                 Object value = getObjectFieldValue(
+                     inputNode,
+                     manyAssociationName,
+                     buildDeserializeInputNodeFunction( new CollectionType( Collection.class,
+                                                                            new ValueType( EntityReference.class ) ) ) );
+                 stateMap.put( manyAssociationName, value );
+             }
+         }
+ 
+         ValueBuilder<?> valueBuilder = buildNewValueBuilderWithState( valueBuilderType, stateMap );
+         return (T) valueBuilder.newInstance(); // Unchecked cast because the builder could use a type != T
+     }
+ 
+     private <T> Function<InputNodeType, T> buildDeserializeInputNodeFunction( final ValueType valueType )
+     {
+         return new Function<InputNodeType, T>()
+         {
+             @Override
+             public T map( InputNodeType inputNode )
+             {
+                 try
+                 {
+                     return doDeserializeInputNodeValue( valueType, inputNode );
+                 }
+                 catch( ValueSerializationException ex )
+                 {
+                     throw ex;
+                 }
+                 catch( Exception ex )
+                 {
+                     throw new ValueSerializationException( ex );
+                 }
+             }
+         };
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T doDeserializeInputNodeValue( ValueType valueType, InputNodeType inputNode )
+         throws Exception
+     {
+         if( inputNode == null )
+         {
+             return null;
+         }
+         final Class<?> type = first( valueType.types() );
+         // Registered deserializers
+         if( deserializers.get( type ) != null )
+         {
+             Object value = asSimpleValue( inputNode );
+             TREE_PARSING_LOG.trace(
+                 "While registered deserializer attempt, asSimpleValue( {} ) returned '{}'",
+                 inputNode, value );
+             if( value == null )
+             {
+                 return null;
+             }
+             return (T) deserializers.get( type ).map( value );
+         }
+         else // Explicit ValueComposite
+         if( ValueCompositeType.class.isAssignableFrom( valueType.getClass() ) )
+         {
+             return (T) deserializeNodeValueComposite( (ValueCompositeType) valueType, inputNode );
+         }
+         else // Explicit Collections
+         if( CollectionType.class.isAssignableFrom( valueType.getClass() ) )
+         {
+             return (T) deserializeNodeCollection( (CollectionType) valueType, inputNode );
+         }
+         else // Explicit Map
+         if( MapType.class.isAssignableFrom( valueType.getClass() ) )
+         {
+             return (T) deserializeNodeMap( (MapType) valueType, inputNode );
+         }
+         else // Enum
+         if( EnumType.class.isAssignableFrom( valueType.getClass() ) || type.isEnum() )
+         {
+             Object value = asSimpleValue( inputNode );
+             TREE_PARSING_LOG.trace(
+                 "While Enum deserialize attempt, asSimpleValue( {} ) returned '{}'",
+                 inputNode, value );
+             if( value == null )
+             {
+                 return null;
+             }
+             return (T) Enum.valueOf( (Class) type, value.toString() );
+         }
+         // Guessed deserialization
+         return (T) deserializeNodeGuessed( valueType, inputNode );
+     }
+ 
+     private ValueBuilder<?> buildNewValueBuilderWithState( Class<?> type, final Map<String, Object> stateMap )
+     {
+         return valuesModule().newValueBuilderWithState(
+             type,
+             new Function<PropertyDescriptor, Object>()
+             {
+                 @Override
+                 public Object map( PropertyDescriptor property )
+                 {
+                     return stateMap.get( property.qualifiedName().name() );
+                 }
+             },
+             new Function<AssociationDescriptor, EntityReference>()
+             {
+                 @Override
+                 public EntityReference map( AssociationDescriptor association )
+                 {
+                     Object entityRef = stateMap.get( association.qualifiedName().name() );
+                     if( entityRef == null )
+                     {
+                         return null;
+                     }
+                     else
+                     {
+                         return (EntityReference) entityRef;
+                     }
+                 }
+             },
+             new Function<AssociationDescriptor, Iterable<EntityReference>>()
+             {
+                 @Override
+                 @SuppressWarnings( "unchecked" )
+                 public Iterable<EntityReference> map( AssociationDescriptor manyAssociation )
+                 {
+                     Object entityRefs = stateMap.get( manyAssociation.qualifiedName().name() );
+                     if( entityRefs == null )
+                     {
+                         return empty();
+                     }
+                     else
+                     {
+                         return (Iterable<EntityReference>) entityRefs;
+                     }
+                 }
+             } );
+ 
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T deserializeGuessed( ValueType valueType, InputType input )
+         throws Exception
+     {
+         InputNodeType inputNode = readObjectTree( input );
+         if( inputNode == null )
+         {
+             return null;
+         }
+         return deserializeNodeGuessed( valueType, inputNode );
+     }
+ 
+     private <T> Collection<T> deserializeNodeCollection( CollectionType collectionType, InputNodeType inputNode )
+         throws Exception
+     {
+         Collection<T> collection;
+         Class<?> collectionMainType = first( collectionType.types() );
+         if( Set.class.equals( collectionMainType ) )
+         {
+             collection = new LinkedHashSet<T>();
+         }
+         else
+         {
+             collection = new ArrayList<T>();
+         }
+         putArrayNodeInCollection( inputNode,
+                                   this.<T>buildDeserializeInputNodeFunction( collectionType.collectedType() ),
+                                   collection );
+         return collection;
+     }
+ 
+     private <K, V> Map<K, V> deserializeNodeMap( MapType mapType, InputNodeType inputNode )
+         throws Exception
+     {
+         Map<K, V> map = new HashMap<K, V>();
+         putArrayNodeInMap( inputNode,
 -                           this.<K>buildDeserializeInputNodeFunction( mapType.getKeyType() ),
 -                           this.<V>buildDeserializeInputNodeFunction( mapType.getValueType() ),
++                           this.<K>buildDeserializeInputNodeFunction( mapType.keyType() ),
++                           this.<V>buildDeserializeInputNodeFunction( mapType.valueType() ),
+                            map );
+         return map;
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T deserializeNodeGuessed( ValueType valueType, InputNodeType inputNode )
+         throws Exception
+     {
+         if( isObjectValue( inputNode ) )
+         {
+             // Attempt ValueComposite deserialization
+             ValueCompositeType valueCompositeType;
+             if( objectHasField( inputNode, "_type" ) ) // with _type info
+             {
+                 String typeInfo = this.<String>getObjectFieldValue(
+                     inputNode,
+                     "_type",
+                     this.<String>buildDeserializeInputNodeFunction( new ValueType( String.class ) ) );
+                 TREE_PARSING_LOG.trace(
+                     "In deserializeNodeGuessed(), getObjectFieldValue( {} ) returned '{}'",
+                     inputNode, typeInfo );
+                 ValueDescriptor valueDescriptor = valuesModule().valueDescriptor( typeInfo );
+                 if( valueDescriptor == null )
+                 {
+                     throw new ValueSerializationException( "Specified value type could not be resolved: " + typeInfo );
+                 }
+                 valueCompositeType = valueDescriptor.valueType();
+                 TREE_PARSING_LOG.debug(
+                     "Overriding {} with {} as defined in _type field.",
+                     valueType, valueCompositeType );
+             }
+             else // without _type info
+             {
+                 ValueDescriptor valueDescriptor = valuesModule().valueDescriptor( first( valueType.types() ).getName() );
+                 if( valueDescriptor == null )
+                 {
+                     throw new ValueSerializationException( "Don't know how to deserialize " + inputNode );
+                 }
+                 valueCompositeType = valueDescriptor.valueType();
+                 TREE_PARSING_LOG.debug(
+                     "Overriding {} with {} as found in available ValueComposites.",
+                     valueType, valueCompositeType );
+             }
+             Class<?> valueBuilderType = first( valueCompositeType.types() );
+             return deserializeValueComposite( valueCompositeType, valueBuilderType, inputNode );
+         }
+         // Last resort : base64 java deserialization
+         return (T) deserializeBase64Serialized( inputNode );
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T deserializeBase64Serialized( InputNodeType inputNode )
+         throws Exception
+     {
+         Object value = asSimpleValue( inputNode );
+         TREE_PARSING_LOG.trace(
+             "While Base64 deserialize attempt, asSimpleValue( {} ) returned '{}'",
+             inputNode, value );
+         if( value == null )
+         {
+             return null;
+         }
+         String base64 = value.toString();
+         return deserializeBase64Serialized( base64 );
+     }
+ 
+     @SuppressWarnings( "unchecked" )
+     private <T> T deserializeBase64Serialized( String inputString )
+         throws Exception
+     {
+         byte[] bytes = inputString.getBytes( UTF_8 );
+         bytes = Base64Encoder.decode( bytes );
+         ObjectInputStream oin = new ObjectInputStream( new ByteArrayInputStream( bytes ) );
+         Object result = oin.readObject();
+         oin.close();
+         return (T) result;
+     }
+ 
+     //
+     // Deserialization Extension Points
+     //
+     /**
+      * Called by the adapter on deserialization start, after {@link #adaptInput(java.io.InputStream)}.
+      *
+      * @throws Exception that will be wrapped in a {@link ValueSerializationException}
+      */
+     protected void onDeserializationStart( ValueType valueType, InputType input )
+         throws Exception
+     {
+         // NOOP
+     }
+ 
+     /**
+      * Called by the adapter on deserialization end.
+      *
+      * @throws Exception that will be wrapped in a {@link ValueSerializationException}
+      */
+     protected void onDeserializationEnd( 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 input InputStream to adapt
+      * @return Adapted input
+      * @throws Exception that will be wrapped in a {@link ValueSerializationException}
+      */
+     protected abstract InputType adaptInput( InputStream input )
+         throws Exception;
+ 
+     /**
+      * @return a Plain Value read from the input
+      * @throws Exception that will be wrapped in a {@link ValueSerializationException}
+      */
+     protected abstract Object readPlainValue( InputType input )
+         throws Exception;
+ 
+     /**
+      * @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( 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>
+      *
+      * @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( InputType input,
+                                                       Function<InputType, K> keyDeserializer,
+                                                       Function<InputType, V> valueDeserializer,
+                                                       Map<K, V> map )
+         throws Exception;
+ 
+     /**
+      * @return an InputNodeType or null if the value was null
+      * @throws Exception that will be wrapped in a {@link ValueSerializationException}
+      */
+     protected abstract InputNodeType readObjectTree( InputType input )
+         throws Exception;
+ 
+     //
+     // Tree Parsing Deserialization
+     //
+     protected abstract Object asSimpleValue( InputNodeType inputNode )
+         throws Exception;
+ 
+     protected abstract boolean isObjectValue( InputNodeType inputNode )
+         throws Exception;
+ 
+     protected abstract boolean objectHasField( InputNodeType inputNode, String key )
+         throws Exception;
+ 
+     /**
+      * Return null if the field do not exists.
+      * @throws Exception that will be wrapped in a {@link ValueSerializationException}
+      */
+     protected abstract <T> T getObjectFieldValue( InputNodeType inputNode,
+                                                   String key,
+                                                   Function<InputNodeType, T> valueDeserializer )
+         throws Exception;
+ 
+     protected abstract <T> void putArrayNodeInCollection( InputNodeType inputNode,
+                                                           Function<InputNodeType, T> deserializer,
+                                                           Collection<T> collection )
+         throws Exception;
+ 
+     protected abstract <K, V> void putArrayNodeInMap( InputNodeType inputNode,
+                                                       Function<InputNodeType, K> keyDeserializer,
+                                                       Function<InputNodeType, V> valueDeserializer,
+                                                       Map<K, V> map )
+         throws Exception;
+ }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e2ea757e/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
----------------------------------------------------------------------
diff --cc core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
index 0000000,fa39a6a..fbefa77
mode 000000,100644..100644
--- a/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
+++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueSerializerAdapter.java
@@@ -1,0 -1,519 +1,519 @@@
+ /*
+  * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+  * Copyright (c) 2010, Niclas Hehdman. All Rights Reserved.
+  * Copyright (c) 2012, Paul Merlin. All Rights Reserved.
+  *
+  * Licensed 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.qi4j.spi.value;
+ 
+ import java.io.ByteArrayOutputStream;
+ import java.io.ObjectOutputStream;
+ import java.io.OutputStream;
+ import java.math.BigDecimal;
+ import java.math.BigInteger;
+ import java.util.Date;
+ import java.util.HashMap;
+ import java.util.Map;
+ import org.joda.time.DateTime;
+ import org.joda.time.LocalDate;
+ import org.joda.time.LocalDateTime;
+ import org.qi4j.api.Qi4j;
+ import org.qi4j.api.association.Association;
+ import org.qi4j.api.association.AssociationDescriptor;
+ import org.qi4j.api.association.AssociationStateHolder;
+ import org.qi4j.api.association.ManyAssociation;
+ import org.qi4j.api.composite.CompositeInstance;
+ import org.qi4j.api.entity.EntityComposite;
+ import org.qi4j.api.entity.EntityReference;
+ import org.qi4j.api.entity.Identity;
+ import org.qi4j.api.property.Property;
+ import org.qi4j.api.property.PropertyDescriptor;
+ import org.qi4j.api.util.Base64Encoder;
+ import org.qi4j.api.util.Dates;
+ import org.qi4j.api.value.ValueComposite;
+ import org.qi4j.api.value.ValueDescriptor;
+ import org.qi4j.api.value.ValueSerializationException;
+ import org.qi4j.api.value.ValueSerializer;
+ import org.qi4j.functional.Function;
+ import org.qi4j.functional.Functions;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import static org.qi4j.functional.Iterables.*;
+ 
+ /**
+  * Adapter for pull-parsing capable ValueSerializers.
+  *
+  * <p>
+  *     Among Plain values (see {@link ValueSerializer}) some are considered primitives to underlying serialization
+  *     mechanisms and by so handed/come without conversion to/from implementations. Primitive values can be one of:
+  * </p>
+  * <ul>
+  *     <li>String,</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>
+  *
+  * @param <OutputType> Implementor output type
+  */
+ public abstract class ValueSerializerAdapter<OutputType>
+     implements ValueSerializer
+ {
+ 
+     private static final Logger LOG = LoggerFactory.getLogger( ValueSerializerAdapter.class );
+     private static final String UTF_8 = "UTF-8";
+     private final Map<Class<?>, Function<Object, Object>> serializers = new HashMap<Class<?>, Function<Object, Object>>();
+ 
+     /**
+      * Register a Plain Value type serialization Function.
+      *
+      * @param <T> Plain Value parametrized Type
+      * @param type Plain Value Type
+      * @param deserializer Serialization Function
+      */
+     @SuppressWarnings( "unchecked" )
+     protected final <T> void registerSerializer( Class<T> type, Function<T, Object> serializer )
+     {
+         serializers.put( type, (Function<Object, Object>) serializer );
+     }
+ 
+     public ValueSerializerAdapter()
+     {
+         // Primitive Value types
+         registerSerializer( String.class, Functions.<Object, String>identity() );
+         registerSerializer( Boolean.class, Functions.<Object, Boolean>identity() );
+         registerSerializer( Integer.class, Functions.<Object, Integer>identity() );
+         registerSerializer( Long.class, Functions.<Object, Long>identity() );
+         registerSerializer( Short.class, Functions.<Object, Short>identity() );
+         registerSerializer( Byte.class, Functions.<Object, Byte>identity() );
+         registerSerializer( Float.class, Functions.<Object, Float>identity() );
+         registerSerializer( Double.class, Functions.<Object, Double>identity() );
+ 
+         // Number types
+         registerSerializer( BigDecimal.class, new Function<BigDecimal, Object>()
+         {
+             @Override
+             public Object map( BigDecimal bigDecimal )
+             {
+                 return bigDecimal.toString();
+             }
+         } );
+         registerSerializer( BigInteger.class, new Function<BigInteger, Object>()
+         {
+             @Override
+             public Object map( BigInteger bigInteger )
+             {
+                 return bigInteger.toString();
+             }
+         } );
+ 
+         // Date types
+         registerSerializer( Date.class, new Function<Date, Object>()
+         {
+             @Override
+             public Object map( Date date )
+             {
+                 return Dates.toUtcString( date );
+             }
+         } );
+         registerSerializer( DateTime.class, new Function<DateTime, Object>()
+         {
+             @Override
+             public Object map( DateTime date )
+             {
+                 return date.toString();
+             }
+         } );
+         registerSerializer( LocalDateTime.class, new Function<LocalDateTime, Object>()
+         {
+             @Override
+             public Object map( LocalDateTime date )
+             {
+                 return date.toString();
+             }
+         } );
+         registerSerializer( LocalDate.class, new Function<LocalDate, Object>()
+         {
+             @Override
+             public Object map( LocalDate date )
+             {
+                 return date.toString();
+             }
+         } );
+ 
+         // Other supported types
+         registerSerializer( EntityReference.class, new Function<EntityReference, Object>()
+         {
+             @Override
+             public Object map( EntityReference ref )
+             {
+                 return ref.toString();
+             }
+         } );
+     }
+ 
+     @Override
+     public final <T> Function<T, String> serialize()
+     {
+         return new Function<T, String>()
+         {
+             @Override
+             public String map( T object )
+             {
+                 return serialize( object );
+             }
+         };
+     }
+ 
+     @Override
+     public final <T> Function<T, String> serialize( final boolean includeTypeInfo )
+     {
+         return new Function<T, String>()
+         {
+             @Override
+             public String map( T object )
+             {
+                 return serialize( object, includeTypeInfo );
+             }
+         };
+     }
+ 
+     @Override
+     public final String serialize( Object object )
+         throws ValueSerializationException
+     {
+         return serialize( object, true );
+     }
+ 
+     @Override
+     public final String serialize( Object object, boolean includeTypeInfo )
+         throws ValueSerializationException
+     {
+         try
+         {
+             ByteArrayOutputStream output = new ByteArrayOutputStream();
+             serializeRoot( object, output, includeTypeInfo );
+             return output.toString( UTF_8 );
+         }
+         catch( ValueSerializationException ex )
+         {
+             throw ex;
+         }
+         catch( Exception ex )
+         {
+             throw new ValueSerializationException( "Could not serialize value", ex );
+         }
+     }
+ 
+     @Override
+     public final void serialize( Object object, OutputStream output )
+         throws ValueSerializationException
+     {
+         serialize( object, output, true );
+     }
+ 
+     @Override
+     public final void serialize( Object object, OutputStream output, boolean includeTypeInfo )
+         throws ValueSerializationException
+     {
+         try
+         {
+             serializeRoot( object, output, includeTypeInfo );
+         }
+         catch( ValueSerializationException ex )
+         {
+             throw ex;
+         }
+         catch( Exception ex )
+         {
+             throw new ValueSerializationException( "Could not serialize value", ex );
+         }
+     }
+ 
+     private void serializeRoot( Object object, OutputStream output, boolean includeTypeInfo )
+         throws Exception
+     {
+         if( object != null )
+         {
+             // System.out.println( ">>>>>>>>>>>> " + ( object == null ? "null" : object.getClass() ) );
+             if( serializers.get( object.getClass() ) != null )
+             {
+                 // Plain Value
+                 Object serialized = serializers.get( object.getClass() ).map( object );
+                 output.write( serialized.toString().getBytes( UTF_8 ) );
+             }
+             else if( object.getClass().isEnum() )
+             {
+                 // Enum Value
+                 output.write( object.toString().getBytes( UTF_8 ) );
+             }
+             else if( object.getClass().isArray() )
+             {
+                 // Array Value
+                 output.write( serializeBase64Serializable( object ).getBytes( UTF_8 ) );
+             }
+             else
+             {
+                 // Complex Value
+                 OutputType adaptedOutput = adaptOutput( output );
+                 onSerializationStart( object, adaptedOutput );
+                 doSerialize( object, adaptedOutput, includeTypeInfo, true );
+                 onSerializationEnd( object, adaptedOutput );
+             }
+         }
+     }
+ 
+     private void doSerialize( Object object, OutputType output, boolean includeTypeInfo, boolean rootPass )
+         throws Exception
+     {
+         // Null
+         if( object == null )
+         {
+             LOG.trace( "Null object -> onValue( null )" );
+             onValue( output, null );
+         }
+         else // Registered serializer
+         if( serializers.get( object.getClass() ) != null )
+         {
+             LOG.trace( "Registered serializer matches -> onValue( serialized )" );
+             onValue( output, serializers.get( object.getClass() ).map( object ) );
+         }
+         else // ValueComposite
+         if( ValueComposite.class.isAssignableFrom( object.getClass() ) )
+         {
+             LOG.trace( "ValueComposite assignable -> serializeValueComposite( object )" );
+             serializeValueComposite( object, output, includeTypeInfo, rootPass );
+         }
+         else // EntityComposite
+         if( EntityComposite.class.isAssignableFrom( object.getClass() ) )
+         {
+             LOG.trace( "EntityComposite assignable -> serializeEntityComposite( object )" );
+             serializeEntityComposite( object, output );
+         }
+         else // Collection - Iterable
+         if( Iterable.class.isAssignableFrom( object.getClass() ) )
+         {
+             LOG.trace( "Iterable assignable -> serializeIterable( object )" );
+             serializeIterable( object, output, includeTypeInfo );
+         }
+         else // Array - QUID Remove this and use java serialization for arrays?
+         if( object.getClass().isArray() )
+         {
+             LOG.trace( "Object isArray -> serializeBase64Serializable( object )" );
+             serializeBase64Serializable( object, output );
+         }
+         else // Map
+         if( Map.class.isAssignableFrom( object.getClass() ) )
+         {
+             LOG.trace( "Map assignable -> serializeMap( object )" );
+             serializeMap( object, output, includeTypeInfo );
+         }
+         else // Enum
+         if( object.getClass().isEnum() )
+         {
+             LOG.trace( "Object is an enum -> onValue( object.toString() )" );
+             onValue( output, object.toString() );
+         }
+         else // Fallback to Base64 encoded Java Serialization
+         {
+             LOG.trace( "Unknown object type -> serializeBase64Serializable( object )" );
+             serializeBase64Serializable( object, output );
+         }
+     }
+ 
+     private void serializeValueComposite( Object object, OutputType output, boolean includeTypeInfo, boolean rootPass )
+         throws Exception
+     {
 -        CompositeInstance valueInstance = Qi4j.INSTANCE_FUNCTION.map( (ValueComposite) object );
++        CompositeInstance valueInstance = Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( (ValueComposite) object );
+         ValueDescriptor descriptor = (ValueDescriptor) valueInstance.descriptor();
+         AssociationStateHolder state = (AssociationStateHolder) valueInstance.state();
+ 
+         onObjectStart( output );
+ 
+         if( includeTypeInfo && !rootPass )
+         {
+             onFieldStart( output, "_type" );
+             onValueStart( output );
+             onValue( output, first( descriptor.valueType().types() ).getName() );
+             onValueEnd( output );
+             onFieldEnd( output );
+         }
+ 
+         for( PropertyDescriptor persistentProperty : descriptor.valueType().properties() )
+         {
+             Property<?> property = state.propertyFor( persistentProperty.accessor() );
+             onFieldStart( output, persistentProperty.qualifiedName().name() );
+             onValueStart( output );
+             doSerialize( property.get(), output, includeTypeInfo, false );
+             onValueEnd( output );
+             onFieldEnd( output );
+         }
+         for( AssociationDescriptor associationDescriptor : descriptor.valueType().associations() )
+         {
+             Association<?> association = state.associationFor( associationDescriptor.accessor() );
+             Object instance = association.get();
+             onFieldStart( output, associationDescriptor.qualifiedName().name() );
+             onValueStart( output );
+             if( instance == null )
+             {
+                 onValue( output, null );
+             }
+             else
+             {
+                 onValue( output, ( (Identity) instance ).identity().get() );
+             }
+             onValueEnd( output );
+             onFieldEnd( output );
+         }
+         for( AssociationDescriptor associationDescriptor : descriptor.valueType().manyAssociations() )
+         {
+             ManyAssociation<?> manyAssociation = state.manyAssociationFor( associationDescriptor.accessor() );
+             onFieldStart( output, associationDescriptor.qualifiedName().name() );
+             onValueStart( output );
+             onArrayStart( output );
+             for( Object instance : manyAssociation )
+             {
+                 onValueStart( output );
+                 onValue( output, ( (Identity) instance ).identity().get() );
+                 onValueEnd( output );
+             }
+             onArrayEnd( output );
+             onValueEnd( output );
+             onFieldEnd( output );
+         }
+ 
+         onObjectEnd( output );
+     }
+ 
+     private void serializeEntityComposite( Object object, OutputType output )
+         throws Exception
+     {
 -        onValue( output, EntityReference.getEntityReference( object ) );
++        onValue( output, EntityReference.entityReferenceFor( object ) );
+     }
+ 
+     private void serializeIterable( Object object, OutputType output, boolean includeTypeInfo )
+         throws Exception
+     {
+         @SuppressWarnings( "unchecked" )
+         Iterable<Object> collection = (Iterable<Object>) object;
+         onArrayStart( output );
+         for( Object item : collection )
+         {
+             onValueStart( output );
+             doSerialize( item, output, includeTypeInfo, false );
+             onValueEnd( output );
+         }
+         onArrayEnd( output );
+     }
+ 
+     private void serializeMap( Object object, OutputType output, boolean includeTypeInfo )
+         throws Exception
+     {
+         @SuppressWarnings( "unchecked" )
+         Map<Object, Object> map = (Map<Object, Object>) object;
+         onArrayStart( output );
+         for( Map.Entry<Object, Object> entry : map.entrySet() )
+         {
+             onObjectStart( output );
+ 
+             onFieldStart( output, "key" );
+             onValueStart( output );
+             onValue( output, entry.getKey().toString() );
+             onValueEnd( output );
+             onFieldEnd( output );
+ 
+             onFieldStart( output, "value" );
+             onValueStart( output );
+             doSerialize( entry.getValue(), output, includeTypeInfo, false );
+             onValueEnd( output );
+             onFieldEnd( output );
+ 
+             onObjectEnd( output );
+         }
+         onArrayEnd( output );
+     }
+ 
+     private void serializeBase64Serializable( Object object, OutputType output )
+         throws Exception
+     {
+         onValue( output, serializeBase64Serializable( object ) );
+     }
+ 
+     private String serializeBase64Serializable( Object object )
+         throws Exception
+     {
+         ByteArrayOutputStream bout = new ByteArrayOutputStream();
+         ObjectOutputStream out = new ObjectOutputStream( bout );
+         out.writeUnshared( object );
+         out.close();
+         byte[] bytes = Base64Encoder.encode( bout.toByteArray(), true );
+         return new String( bytes, UTF_8 );
+     }
+ 
+     protected abstract OutputType adaptOutput( OutputStream output )
+         throws Exception;
+ 
+     protected void onSerializationStart( Object object, OutputType output )
+         throws Exception
+     {
+         // NOOP
+     }
+ 
+     protected void onSerializationEnd( Object object, OutputType output )
+         throws Exception
+     {
+         // NOOP
+     }
+ 
+     protected abstract void onArrayStart( OutputType output )
+         throws Exception;
+ 
+     protected abstract void onArrayEnd( OutputType output )
+         throws Exception;
+ 
+     protected abstract void onObjectStart( OutputType output )
+         throws Exception;
+ 
+     protected abstract void onObjectEnd( OutputType output )
+         throws Exception;
+ 
+     protected abstract void onFieldStart( OutputType output, String fieldName )
+         throws Exception;
+ 
+     protected void onFieldEnd( OutputType output )
+         throws Exception
+     {
+         // NOOP
+     }
+ 
+     protected void onValueStart( OutputType output )
+         throws Exception
+     {
+         // NOOP
+     }
+ 
+     protected abstract void onValue( OutputType output, Object value )
+         throws Exception;
+ 
+     protected void onValueEnd( OutputType output )
+         throws Exception
+     {
+         // NOOP
+     }
+ }