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 2016/12/17 10:27:41 UTC

[05/81] [abbrv] [partial] zest-java git commit: ZEST-195 ; Replace all "zest" with "polygene"

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/unitofwork/UnitOfWorkInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/unitofwork/UnitOfWorkInstance.java b/core/runtime/src/main/java/org/apache/polygene/runtime/unitofwork/UnitOfWorkInstance.java
new file mode 100644
index 0000000..81e4907
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/unitofwork/UnitOfWorkInstance.java
@@ -0,0 +1,510 @@
+/*
+ *  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.runtime.unitofwork;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import org.apache.polygene.api.common.MetaInfo;
+import org.apache.polygene.api.entity.EntityComposite;
+import org.apache.polygene.api.entity.EntityDescriptor;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.metrics.MetricNames;
+import org.apache.polygene.api.metrics.MetricsCounter;
+import org.apache.polygene.api.metrics.MetricsCounterFactory;
+import org.apache.polygene.api.metrics.MetricsProvider;
+import org.apache.polygene.api.metrics.MetricsTimer;
+import org.apache.polygene.api.metrics.MetricsTimerFactory;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.HasTypes;
+import org.apache.polygene.api.unitofwork.ConcurrentEntityModificationException;
+import org.apache.polygene.api.unitofwork.NoSuchEntityException;
+import org.apache.polygene.api.unitofwork.NoSuchEntityTypeException;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.unitofwork.UnitOfWorkCallback;
+import org.apache.polygene.api.unitofwork.UnitOfWorkCompletionException;
+import org.apache.polygene.api.unitofwork.UnitOfWorkException;
+import org.apache.polygene.api.unitofwork.UnitOfWorkOptions;
+import org.apache.polygene.api.usecase.Usecase;
+import org.apache.polygene.runtime.entity.EntityInstance;
+import org.apache.polygene.runtime.entity.EntityModel;
+import org.apache.polygene.spi.entity.EntityState;
+import org.apache.polygene.spi.entity.EntityStatus;
+import org.apache.polygene.spi.entitystore.ConcurrentEntityStateModificationException;
+import org.apache.polygene.spi.entitystore.EntityNotFoundException;
+import org.apache.polygene.spi.entitystore.EntityStore;
+import org.apache.polygene.spi.entitystore.EntityStoreUnitOfWork;
+import org.apache.polygene.spi.entitystore.StateCommitter;
+import org.apache.polygene.spi.module.ModuleSpi;
+
+import static org.apache.polygene.api.unitofwork.UnitOfWorkCallback.UnitOfWorkStatus.COMPLETED;
+import static org.apache.polygene.api.unitofwork.UnitOfWorkCallback.UnitOfWorkStatus.DISCARDED;
+
+public final class UnitOfWorkInstance
+{
+    private static final ThreadLocal<Stack<UnitOfWorkInstance>> CURRENT = new ThreadLocal<Stack<UnitOfWorkInstance>>()
+    {
+        @Override
+        protected Stack<UnitOfWorkInstance> initialValue()
+        {
+            return new Stack<>();
+        }
+    };
+
+    public static Stack<UnitOfWorkInstance> getCurrent()
+    {
+        return CURRENT.get();
+    }
+
+    private final HashMap<EntityReference, EntityInstance> instanceCache = new HashMap<>();
+    private final HashMap<EntityStore, EntityStoreUnitOfWork> storeUnitOfWork = new HashMap<>();
+    private final ModuleSpi module;
+    private final Usecase usecase;
+    private final Instant currentTime;
+    private final MetricsProvider metrics;
+
+    private boolean open;
+    private boolean paused;
+
+    private MetricsCounter metricsCounter;
+    private MetricsTimer metricsTimer;
+    private MetricsTimer.Context metricsTimerContext;
+    private MetaInfo metaInfo;
+    private List<UnitOfWorkCallback> callbacks;
+
+    public UnitOfWorkInstance(ModuleSpi module, Usecase usecase, Instant currentTime, MetricsProvider metrics )
+    {
+        this.module = module;
+        this.usecase = usecase;
+        this.currentTime = currentTime;
+        this.metrics = metrics;
+
+        this.open = true;
+        getCurrent().push( this );
+        this.paused = false;
+        startCapture();
+    }
+
+    public Instant currentTime()
+    {
+        return currentTime;
+    }
+
+    public EntityStoreUnitOfWork getEntityStoreUnitOfWork( EntityStore store )
+    {
+        EntityStoreUnitOfWork uow = storeUnitOfWork.get( store );
+        if( uow == null )
+        {
+            uow = store.newUnitOfWork( module.descriptor(), usecase, currentTime );
+            storeUnitOfWork.put( store, uow );
+        }
+        return uow;
+    }
+
+    public <T> T get( EntityReference reference,
+                      UnitOfWork uow,
+                      Iterable<? extends EntityDescriptor> potentialModels,
+                      Class<T> mixinType
+    )
+        throws NoSuchEntityTypeException, NoSuchEntityException
+    {
+        checkOpen();
+
+        EntityInstance entityInstance = instanceCache.get( reference );
+        if( entityInstance == null )
+        {   // Not yet in cache
+
+            // Check if this is a root UoW, or if no parent UoW knows about this entity
+            EntityState entityState = null;
+            EntityModel model = null;
+            ModuleDescriptor module = null;
+            // Figure out what EntityStore to use
+            for( EntityDescriptor potentialModel : potentialModels )
+            {
+                EntityStore store = ((ModuleSpi) potentialModel.module().instance()).entityStore();
+                EntityStoreUnitOfWork storeUow = getEntityStoreUnitOfWork( store );
+                try
+                {
+                    entityState = storeUow.entityStateOf( potentialModel.module(), reference );
+                }
+                catch( EntityNotFoundException e )
+                {
+                    continue;
+                }
+
+                // Get the selected model
+                model = (EntityModel) entityState.entityDescriptor();
+                module = potentialModel.module();
+            }
+
+            // Check if model was found
+            if( model == null )
+            {
+                // Check if state was found
+                if( entityState == null )
+                {
+                    throw new NoSuchEntityException( reference, mixinType, usecase );
+                }
+                else
+                {
+                    throw new NoSuchEntityTypeException( mixinType.getName(), module.name(), module.typeLookup() );
+                }
+            }
+            // Create instance
+            entityInstance = new EntityInstance( uow, model, entityState );
+            instanceCache.put( reference, entityInstance );
+        }
+        else
+        {
+            // Check if it has been removed
+            if( entityInstance.status() == EntityStatus.REMOVED )
+            {
+                throw new NoSuchEntityException( reference, mixinType, usecase );
+            }
+        }
+
+        return entityInstance.proxy();
+    }
+
+    public Usecase usecase()
+    {
+        return usecase;
+    }
+
+    public MetaInfo metaInfo()
+    {
+        if( metaInfo == null )
+        {
+            metaInfo = new MetaInfo();
+        }
+
+        return metaInfo;
+    }
+
+    public void pause()
+    {
+        if( !paused )
+        {
+            paused = true;
+            getCurrent().pop();
+
+            UnitOfWorkOptions unitOfWorkOptions = metaInfo().get( UnitOfWorkOptions.class );
+            if( unitOfWorkOptions == null )
+            {
+                unitOfWorkOptions = usecase().metaInfo( UnitOfWorkOptions.class );
+            }
+
+            if( unitOfWorkOptions != null )
+            {
+                if( unitOfWorkOptions.isPruneOnPause() )
+                {
+                    List<EntityReference> prunedInstances = null;
+                    for( EntityInstance entityInstance : instanceCache.values() )
+                    {
+                        if( entityInstance.status() == EntityStatus.LOADED )
+                        {
+                            if( prunedInstances == null )
+                            {
+                                prunedInstances = new ArrayList<>();
+                            }
+                            prunedInstances.add( entityInstance.reference() );
+                        }
+                    }
+                    if( prunedInstances != null )
+                    {
+                        prunedInstances.forEach( instanceCache::remove );
+                    }
+                }
+            }
+        }
+        else
+        {
+            throw new UnitOfWorkException( "Unit of work is not active" );
+        }
+    }
+
+    public void resume()
+    {
+        if( paused )
+        {
+            paused = false;
+            getCurrent().push( this );
+        }
+        else
+        {
+            throw new UnitOfWorkException( "Unit of work has not been paused" );
+        }
+    }
+
+    public void complete()
+        throws UnitOfWorkCompletionException
+    {
+        checkOpen();
+
+        // Copy list so that it cannot be modified during completion
+        List<UnitOfWorkCallback> currentCallbacks = callbacks == null ? null : new ArrayList<>( callbacks );
+
+        // Commit state to EntityStores
+        List<StateCommitter> committers = applyChanges();
+
+        // Check callbacks
+        notifyBeforeCompletion( currentCallbacks );
+
+        // Commit all changes
+        committers.forEach( StateCommitter::commit );
+
+        close();
+
+        // Call callbacks
+        notifyAfterCompletion( currentCallbacks, COMPLETED );
+
+        callbacks = currentCallbacks;
+    }
+
+    public void discard()
+    {
+        if( !isOpen() )
+        {
+            return;
+        }
+        close();
+
+        // Copy list so that it cannot be modified during completion
+        List<UnitOfWorkCallback> currentCallbacks = callbacks == null ? null : new ArrayList<>( callbacks );
+
+        // Call callbacks
+        notifyAfterCompletion( currentCallbacks, DISCARDED );
+        storeUnitOfWork.values().forEach( EntityStoreUnitOfWork::discard );
+        callbacks = currentCallbacks;
+    }
+
+    private void close()
+    {
+        checkOpen();
+
+        if( !isPaused() )
+        {
+            getCurrent().pop();
+        }
+        endCapture();
+        open = false;
+    }
+
+    public boolean isOpen()
+    {
+        return open;
+    }
+
+    public void addUnitOfWorkCallback( UnitOfWorkCallback callback )
+    {
+        if( callbacks == null )
+        {
+            callbacks = new ArrayList<>();
+        }
+
+        callbacks.add( callback );
+    }
+
+    public void removeUnitOfWorkCallback( UnitOfWorkCallback callback )
+    {
+        if( callbacks != null )
+        {
+            callbacks.remove( callback );
+        }
+    }
+
+    public void addEntity( EntityInstance instance )
+    {
+        instanceCache.put( instance.reference(), instance );
+    }
+
+    private List<StateCommitter> applyChanges()
+        throws UnitOfWorkCompletionException
+    {
+        List<StateCommitter> committers = new ArrayList<>();
+        for( EntityStoreUnitOfWork entityStoreUnitOfWork : storeUnitOfWork.values() )
+        {
+            try
+            {
+                StateCommitter committer = entityStoreUnitOfWork.applyChanges();
+                committers.add( committer );
+            }
+            catch( Exception e )
+            {
+                // Cancel all previously prepared stores
+                committers.forEach( StateCommitter::cancel );
+
+                if( e instanceof ConcurrentEntityStateModificationException )
+                {
+                    // If we cancelled due to concurrent modification, then create the proper exception for it!
+                    ConcurrentEntityStateModificationException mee = (ConcurrentEntityStateModificationException) e;
+                    Collection<EntityReference> modifiedEntityIdentities = mee.modifiedEntities();
+                    Map<EntityComposite, HasTypes> modifiedEntities = new HashMap<>();
+                    for( EntityReference modifiedEntityIdentity : modifiedEntityIdentities )
+                    {
+                        instanceCache.values().stream()
+                            .filter( instance -> instance.reference().equals( modifiedEntityIdentity ) )
+                            .forEach( instance -> modifiedEntities.put( instance.<EntityComposite>proxy(), instance ) );
+                    }
+                    throw new ConcurrentEntityModificationException( modifiedEntities, usecase );
+                }
+                else
+                {
+                    throw new UnitOfWorkCompletionException( e );
+                }
+            }
+        }
+        return committers;
+    }
+
+    private void notifyBeforeCompletion( List<UnitOfWorkCallback> callbacks )
+        throws UnitOfWorkCompletionException
+    {
+        // Notify explicitly registered callbacks
+        if( callbacks != null )
+        {
+            callbacks.forEach( UnitOfWorkCallback::beforeCompletion );
+        }
+
+        // Notify entities
+        try
+        {
+            for( EntityInstance instance : instanceCache.values() )
+            {
+                boolean isCallback = instance.proxy() instanceof UnitOfWorkCallback;
+                boolean isNotRemoved = !instance.status().equals( EntityStatus.REMOVED );
+                if( isCallback && isNotRemoved )
+                {
+                    UnitOfWorkCallback callback = UnitOfWorkCallback.class.cast( instance.proxy() );
+                    callback.beforeCompletion();
+                }
+            }
+        }
+        catch( UnitOfWorkCompletionException e )
+        {
+            throw e;
+        }
+        catch( Exception e )
+        {
+            throw new UnitOfWorkCompletionException( e );
+        }
+    }
+
+    private void notifyAfterCompletion( List<UnitOfWorkCallback> callbacks,
+                                        final UnitOfWorkCallback.UnitOfWorkStatus status
+    )
+    {
+        if( callbacks != null )
+        {
+            for( UnitOfWorkCallback callback : callbacks )
+            {
+                try
+                {
+                    callback.afterCompletion( status );
+                }
+                catch( Exception e )
+                {
+                    // Ignore
+                }
+            }
+        }
+
+        // Notify entities
+        try
+        {
+            for( EntityInstance instance : instanceCache.values() )
+            {
+                boolean isCallback = instance.proxy() instanceof UnitOfWorkCallback;
+                boolean isNotRemoved = !instance.status().equals( EntityStatus.REMOVED );
+                if( isCallback && isNotRemoved )
+                {
+                    UnitOfWorkCallback callback = UnitOfWorkCallback.class.cast( instance.proxy() );
+                    callback.afterCompletion( status );
+                }
+            }
+        }
+        catch( Exception e )
+        {
+            // Ignore
+        }
+    }
+
+    public void checkOpen()
+    {
+        if( !isOpen() )
+        {
+            throw new UnitOfWorkException( "Unit of work has been closed" );
+        }
+    }
+
+    public boolean isPaused()
+    {
+        return paused;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "UnitOfWork " + hashCode() + "(" + usecase + "): entities:" + instanceCache.size();
+    }
+
+    public void remove( EntityReference entityReference )
+    {
+        instanceCache.remove( entityReference );
+    }
+
+    private void startCapture()
+    {
+        getMetricsCounter().increment();
+        metricsTimerContext = getMetricsTimer().start();
+    }
+
+    private void endCapture()
+    {
+        getMetricsCounter().decrement();
+        metricsTimerContext.stop();
+        metricsTimerContext = null;
+    }
+
+    private MetricsCounter getMetricsCounter()
+    {
+        if( metricsCounter == null )
+        {
+            MetricsCounterFactory metricsFactory = metrics.createFactory( MetricsCounterFactory.class );
+            metricsCounter = metricsFactory.createCounter( MetricNames.nameFor( module, UnitOfWork.class, "counter" ) );
+        }
+        return metricsCounter;
+    }
+
+    private MetricsTimer getMetricsTimer()
+    {
+        if( metricsTimer == null )
+        {
+            MetricsTimerFactory metricsFactory = metrics.createFactory( MetricsTimerFactory.class );
+            metricsTimer = metricsFactory.createTimer( MetricNames.nameFor( module, UnitOfWork.class, "timer" ) );
+        }
+        return metricsTimer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ManyAssociationValueState.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ManyAssociationValueState.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ManyAssociationValueState.java
new file mode 100644
index 0000000..c386802
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ManyAssociationValueState.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.runtime.value;
+
+import java.util.Iterator;
+import java.util.List;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.spi.entity.ManyAssociationState;
+
+/**
+ * ManyAssociationState implementation for Value composites.
+ */
+public class ManyAssociationValueState
+    implements ManyAssociationState
+{
+    private List<EntityReference> references;
+
+    public ManyAssociationValueState( List<EntityReference> references )
+    {
+        this.references = references;
+    }
+
+    @Override
+    public int count()
+    {
+        return references.size();
+    }
+
+    @Override
+    public boolean contains( EntityReference entityReference )
+    {
+        return references.contains( entityReference );
+    }
+
+    @Override
+    public boolean add( int i, EntityReference entityReference )
+    {
+        if( references.contains( entityReference ) )
+        {
+            return false;
+        }
+
+        references.add( i, entityReference );
+        return true;
+    }
+
+    @Override
+    public boolean remove( EntityReference entity )
+    {
+        boolean removed = references.remove( entity );
+        return removed;
+    }
+
+    @Override
+    public EntityReference get( int i )
+    {
+        return references.get( i );
+    }
+
+    @Override
+    public Iterator<EntityReference> iterator()
+    {
+        final Iterator<EntityReference> iter = references.iterator();
+
+        return new Iterator<EntityReference>()
+        {
+            EntityReference current;
+
+            @Override
+            public boolean hasNext()
+            {
+                return iter.hasNext();
+            }
+
+            @Override
+            public EntityReference next()
+            {
+                current = iter.next();
+                return current;
+            }
+
+            @Override
+            public void remove()
+            {
+                iter.remove();
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/NamedAssociationValueState.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/NamedAssociationValueState.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/NamedAssociationValueState.java
new file mode 100644
index 0000000..50c20ca
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/NamedAssociationValueState.java
@@ -0,0 +1,85 @@
+/*
+ *  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.runtime.value;
+
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.spi.entity.NamedAssociationState;
+
+public class NamedAssociationValueState
+    implements NamedAssociationState
+{
+    private final Map<String, EntityReference> references;
+
+    public NamedAssociationValueState( Map<String, EntityReference> references )
+    {
+        this.references = references;
+    }
+
+    @Override
+    public int count()
+    {
+        return references.size();
+    }
+
+    @Override
+    public boolean containsName( String name )
+    {
+        return references.containsKey( name );
+    }
+
+    @Override
+    public boolean put( String name, EntityReference entityReference )
+    {
+        return references.put( name, entityReference ) != null;
+    }
+
+    @Override
+    public boolean remove( String name )
+    {
+        return references.remove( name ) != null;
+    }
+
+    @Override
+    public EntityReference get( String name )
+    {
+        return references.get( name );
+    }
+
+    @Override
+    public String nameOf( EntityReference entityReference )
+    {
+        for( Map.Entry<String, EntityReference> entry : references.entrySet() )
+        {
+            if( entry.getValue().equals( entityReference ) )
+            {
+                return entry.getKey();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Iterator<String> iterator()
+    {
+        return references.keySet().iterator();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ReferenceProperty.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ReferenceProperty.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ReferenceProperty.java
new file mode 100644
index 0000000..6dd6d18
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ReferenceProperty.java
@@ -0,0 +1,54 @@
+/*
+ *  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.runtime.value;
+
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.property.Property;
+
+/**
+ * The reference for an Association
+ */
+public class ReferenceProperty
+    implements Property<EntityReference>
+{
+    EntityReference reference;
+
+    public ReferenceProperty()
+    {
+    }
+
+    public ReferenceProperty( EntityReference reference )
+    {
+        this.reference = reference;
+    }
+
+    @Override
+    public EntityReference get()
+    {
+        return reference;
+    }
+
+    @Override
+    public void set( EntityReference newValue )
+        throws IllegalArgumentException, IllegalStateException
+    {
+        reference = newValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderInstance.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderInstance.java
new file mode 100644
index 0000000..7ecb745
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderInstance.java
@@ -0,0 +1,86 @@
+/*
+ *  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.runtime.value;
+
+import org.apache.polygene.api.association.AssociationStateHolder;
+import org.apache.polygene.api.common.ConstructionException;
+import org.apache.polygene.api.composite.Composite;
+import org.apache.polygene.api.value.NoSuchValueException;
+import org.apache.polygene.api.value.ValueBuilder;
+import org.apache.polygene.api.value.ValueDescriptor;
+import org.apache.polygene.runtime.composite.StateResolver;
+import org.apache.polygene.runtime.structure.ModuleInstance;
+
+/**
+ * Implementation of ValueBuilder
+ */
+public final class ValueBuilderInstance<T>
+    implements ValueBuilder<T>
+{
+
+    private final ModuleInstance currentModule;
+    private final ValueInstance prototypeInstance;
+
+    public ValueBuilderInstance( ValueDescriptor compositeModel,
+                                 ModuleInstance currentModule,
+                                 StateResolver stateResolver
+    )
+    {
+        ValueStateInstance state = new ValueStateInstance( compositeModel, currentModule, stateResolver );
+        ValueModel model = (ValueModel) compositeModel;
+        prototypeInstance = model.newValueInstance( state );
+        prototypeInstance.prepareToBuild();
+        this.currentModule = currentModule;
+    }
+
+    @Override
+    public T prototype()
+    {
+        return prototypeInstance.<T>proxy();
+    }
+
+    @Override
+    public AssociationStateHolder state()
+    {
+        return prototypeInstance.state();
+    }
+
+    @Override
+    public <K> K prototypeFor( Class<K> mixinType )
+    {
+        return prototypeInstance.newProxy( mixinType );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public T newInstance()
+        throws ConstructionException
+    {
+        Class<Composite> valueType = (Class<Composite>) prototypeInstance.types().findFirst().orElse( null );
+
+        ValueDescriptor valueModel = currentModule.typeLookup().lookupValueModel( valueType );
+
+        if( valueModel == null )
+        {
+            throw new NoSuchValueException( valueType.getName(), currentModule.name(), currentModule.typeLookup() );
+        }
+        return new ValueBuilderWithPrototype<>( valueModel, currentModule, prototype() ).newInstance();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithPrototype.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithPrototype.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithPrototype.java
new file mode 100644
index 0000000..c9a1023
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithPrototype.java
@@ -0,0 +1,202 @@
+/*
+ *  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.runtime.value;
+
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.association.AssociationStateHolder;
+import org.apache.polygene.api.common.ConstructionException;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.value.ValueBuilder;
+import org.apache.polygene.api.value.ValueComposite;
+import org.apache.polygene.api.value.ValueDescriptor;
+import org.apache.polygene.runtime.composite.FunctionStateResolver;
+import org.apache.polygene.runtime.composite.MixinModel;
+import org.apache.polygene.runtime.composite.MixinsModel;
+import org.apache.polygene.runtime.composite.StateResolver;
+import org.apache.polygene.runtime.composite.UsesInstance;
+import org.apache.polygene.runtime.injection.InjectionContext;
+import org.apache.polygene.runtime.structure.ModuleInstance;
+
+/**
+ * Implementation of ValueBuilder with a prototype supplied
+ */
+public class ValueBuilderWithPrototype<T>
+    implements ValueBuilder<T>
+{
+    private ValueInstance prototypeInstance;
+    private final ValueModel valueModel;
+
+    public ValueBuilderWithPrototype( ValueDescriptor compositeModelModule,
+                                      ModuleInstance currentModule,
+                                      T prototype
+    )
+    {
+        valueModel = (ValueModel) compositeModelModule;
+        MixinsModel mixinsModel = valueModel.mixinsModel();
+        Object[] mixins = mixinsModel.newMixinHolder();
+        final ValueStateInstance prototypeState = ValueInstance.valueInstanceOf( (ValueComposite) prototype ).state();
+        StateResolver resolver = new FunctionStateResolver(
+            new PropertyDescriptorFunction( prototypeState ),
+            new AssociationDescriptorEntityReferenceFunction( prototypeState ),
+            new AssociationDescriptorIterableFunction( prototypeState ),
+            new AssociationDescriptorMapFunction( prototypeState )
+        );
+        ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, resolver );
+        ValueInstance valueInstance = new ValueInstance(
+            valueModel,
+            mixins,
+            state
+        );
+
+        int i = 0;
+        InjectionContext injectionContext = new InjectionContext( valueInstance, UsesInstance.EMPTY_USES, state );
+        for( MixinModel mixinModel : mixinsModel.mixinModels() )
+        {
+            mixins[ i++ ] = mixinModel.newInstance( injectionContext );
+        }
+
+        valueInstance.prepareToBuild();
+        this.prototypeInstance = valueInstance;
+    }
+
+    @Override
+    public T prototype()
+    {
+        verifyUnderConstruction();
+        return prototypeInstance.<T>proxy();
+    }
+
+    @Override
+    public AssociationStateHolder state()
+    {
+        verifyUnderConstruction();
+        return prototypeInstance.state();
+    }
+
+    @Override
+    public <K> K prototypeFor( Class<K> mixinType )
+    {
+        verifyUnderConstruction();
+        return prototypeInstance.newProxy( mixinType );
+    }
+
+    @Override
+    public T newInstance()
+        throws ConstructionException
+    {
+        verifyUnderConstruction();
+
+        // Set correct info's (immutable) on the state
+        prototypeInstance.prepareBuilderState();
+
+        // Check that it is valid
+        valueModel.checkConstraints( prototypeInstance.state() );
+
+        try
+        {
+            return prototypeInstance.<T>proxy();
+        }
+        finally
+        {
+            // Invalidate builder
+            prototypeInstance = null;
+        }
+    }
+
+    private void verifyUnderConstruction()
+    {
+        if( prototypeInstance == null )
+        {
+            throw new IllegalStateException( "ValueBuilder instances cannot be reused" );
+        }
+    }
+
+    private static class PropertyDescriptorFunction
+        implements Function<PropertyDescriptor, Object>
+    {
+        private final ValueStateInstance prototypeState;
+
+        public PropertyDescriptorFunction( ValueStateInstance prototypeState )
+        {
+            this.prototypeState = prototypeState;
+        }
+
+        @Override
+        public Object apply( PropertyDescriptor descriptor )
+        {
+            return prototypeState.propertyFor( descriptor.accessor() ).get();
+        }
+    }
+
+    private static class AssociationDescriptorEntityReferenceFunction
+        implements Function<AssociationDescriptor, EntityReference>
+    {
+        private final ValueStateInstance prototypeState;
+
+        public AssociationDescriptorEntityReferenceFunction( ValueStateInstance prototypeState )
+        {
+            this.prototypeState = prototypeState;
+        }
+
+        @Override
+        public EntityReference apply( AssociationDescriptor descriptor )
+        {
+            return prototypeState.associationFor( descriptor.accessor() ).reference();
+        }
+    }
+
+    private static class AssociationDescriptorIterableFunction
+        implements Function<AssociationDescriptor, Stream<EntityReference>>
+    {
+        private final ValueStateInstance prototypeState;
+
+        public AssociationDescriptorIterableFunction( ValueStateInstance prototypeState )
+        {
+            this.prototypeState = prototypeState;
+        }
+
+        @Override
+        public Stream<EntityReference> apply( AssociationDescriptor descriptor )
+        {
+            return prototypeState.manyAssociationFor( descriptor.accessor() ).references();
+        }
+    }
+
+    private static class AssociationDescriptorMapFunction
+        implements Function<AssociationDescriptor, Stream<Map.Entry<String, EntityReference>>>
+    {
+        private final ValueStateInstance prototypeState;
+
+        public AssociationDescriptorMapFunction( ValueStateInstance prototypeState )
+        {
+            this.prototypeState = prototypeState;
+        }
+
+        @Override
+        public Stream<Map.Entry<String, EntityReference>> apply( AssociationDescriptor descriptor )
+        {
+            return prototypeState.namedAssociationFor( descriptor.accessor() ).references();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithState.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithState.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithState.java
new file mode 100644
index 0000000..236e3b9
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueBuilderWithState.java
@@ -0,0 +1,97 @@
+/*
+ *  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.runtime.value;
+
+import org.apache.polygene.api.association.AssociationStateHolder;
+import org.apache.polygene.api.common.ConstructionException;
+import org.apache.polygene.api.value.ValueBuilder;
+import org.apache.polygene.api.value.ValueDescriptor;
+import org.apache.polygene.runtime.composite.StateResolver;
+import org.apache.polygene.runtime.structure.ModuleInstance;
+
+public class ValueBuilderWithState<T> implements ValueBuilder<T>
+{
+    private final ValueDescriptor model;
+    private ValueInstance prototypeInstance;
+
+    public ValueBuilderWithState( ValueDescriptor compositeModelModule,
+                                  ModuleInstance currentModule,
+                                  StateResolver stateResolver )
+    {
+        ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, stateResolver );
+        ValueInstance instance = ((ValueModel) compositeModelModule).newValueInstance( state );
+        instance.prepareToBuild();
+        this.model = compositeModelModule;
+        this.prototypeInstance = instance;
+    }
+
+    @Override
+    public T prototype()
+    {
+        verifyUnderConstruction();
+        return prototypeInstance.<T>proxy();
+    }
+
+    @Override
+    public AssociationStateHolder state()
+    {
+        verifyUnderConstruction();
+        return prototypeInstance.state();
+    }
+
+    @Override
+    public <K> K prototypeFor( Class<K> mixinType )
+    {
+        verifyUnderConstruction();
+
+        return prototypeInstance.newProxy( mixinType );
+    }
+
+    @Override
+    public T newInstance()
+        throws ConstructionException
+    {
+        verifyUnderConstruction();
+
+        // Set correct info's (immutable) on the state
+        prototypeInstance.prepareBuilderState();
+
+        // Check that it is valid
+        ((ValueModel) model).checkConstraints( prototypeInstance.state() );
+
+        try
+        {
+            return prototypeInstance.<T>proxy();
+        }
+        finally
+        {
+            // Invalidate builder
+            prototypeInstance = null;
+        }
+    }
+
+    private void verifyUnderConstruction()
+    {
+        if( prototypeInstance == null )
+        {
+            throw new IllegalStateException( "ValueBuilder instances cannot be reused" );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueInstance.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueInstance.java
new file mode 100644
index 0000000..12ba7d9
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueInstance.java
@@ -0,0 +1,172 @@
+/*
+ *  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.runtime.value;
+
+import java.lang.reflect.Proxy;
+import org.apache.polygene.api.composite.CompositeInstance;
+import org.apache.polygene.api.value.ValueComposite;
+import org.apache.polygene.runtime.composite.MixinsInstance;
+import org.apache.polygene.runtime.composite.TransientInstance;
+import org.apache.polygene.runtime.property.PropertyInstance;
+import org.apache.polygene.spi.module.ModuleSpi;
+
+/**
+ * ValueComposite instance
+ */
+public final class ValueInstance
+    extends TransientInstance
+    implements CompositeInstance, MixinsInstance
+{
+    public static ValueInstance valueInstanceOf( ValueComposite composite )
+    {
+        return (ValueInstance) Proxy.getInvocationHandler( composite );
+    }
+
+    public ValueInstance( ValueModel compositeModel,
+                          Object[] mixins,
+                          ValueStateInstance state
+    )
+    {
+        super( compositeModel, mixins, state );
+    }
+
+    /**
+     * Perform equals with {@code o} argument.
+     * <p>
+     * The definition of equals() for the Value is that if both the state and descriptor are equal,
+     * then the values are equal.
+     * </p>
+     *
+     * @param o The other object to compare.
+     *
+     * @return Returns a {@code boolean} indicator whether this object is equals the other.
+     */
+    @Override
+    public boolean equals( Object o )
+    {
+        if( this == o )
+        {
+            return true;
+        }
+        if( o == null || !Proxy.isProxyClass( o.getClass() ) )
+        {
+            return false;
+        }
+
+        try
+        {
+            ValueInstance that = (ValueInstance) Proxy.getInvocationHandler( o );
+            // Descriptor equality
+            if( !descriptor().equals( that.descriptor() ) )
+            {
+                return false;
+            }
+            // State equality
+            return state.equals( that.state );
+        }
+        catch( ClassCastException e )
+        {
+            return false;
+        }
+    }
+
+    @Override
+    public ValueStateInstance state()
+    {
+        return (ValueStateInstance) state;
+    }
+
+    @Override
+    public ValueModel descriptor()
+    {
+        return (ValueModel) compositeModel;
+    }
+
+    /**
+     * When a ValueBuilder is about to start, ensure that all state has builder infos, i.e. they are mutable.
+     */
+    public void prepareToBuild()
+    {
+        descriptor().state().properties().forEach( propertyDescriptor -> {
+            PropertyInstance<Object> propertyInstance =
+                (PropertyInstance<Object>) state.propertyFor( propertyDescriptor.accessor() );
+
+            propertyInstance.prepareToBuild( propertyDescriptor );
+        } );
+
+        descriptor().state().associations().forEach( associationDescriptor -> {
+            state().associationFor( associationDescriptor.accessor() )
+                .setAssociationInfo( associationDescriptor.getBuilderInfo() );
+        } );
+
+        descriptor().state().manyAssociations().forEach( associationDescriptor -> {
+            state().manyAssociationFor( associationDescriptor.accessor() )
+                .setAssociationInfo( associationDescriptor.getBuilderInfo() );
+        } );
+
+        descriptor().state().namedAssociations().forEach( associationDescriptor -> {
+            state().namedAssociationFor( associationDescriptor.accessor() )
+                .setAssociationInfo( associationDescriptor.getBuilderInfo() );
+        } );
+    }
+
+    /**
+     * When a ValueBuilder is finished and is about to instantiate a Value, call this to ensure that the state has correct
+     * settings, i.e. is immutable.
+     */
+    public void prepareBuilderState()
+    {
+        descriptor().state().properties().forEach( propertyDescriptor -> {
+            PropertyInstance<Object> propertyInstance =
+                (PropertyInstance<Object>) state.propertyFor( propertyDescriptor.accessor() );
+            propertyInstance.prepareBuilderState( propertyDescriptor );
+        } );
+
+        descriptor().state().associations().forEach( associationDescriptor -> {
+            state().associationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor );
+        } );
+
+        descriptor().state().manyAssociations().forEach( associationDescriptor -> {
+            state().manyAssociationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor );
+        } );
+
+        descriptor().state().namedAssociations().forEach( associationDescriptor -> {
+            state().namedAssociationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor );
+        } );
+    }
+
+    /**
+     * Calculate hash code.
+     *
+     * @return the hashcode of this instance.
+     */
+    @Override
+    public int hashCode()
+    {
+        int hash = compositeModel.hashCode() * 23; // Descriptor
+        return hash + state.hashCode() * 5; // State
+    }
+
+    @Override
+    public String toString()
+    {
+        return ( (ModuleSpi) module().instance() ).valueSerialization().serialize( this.<ValueComposite>proxy() );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueModel.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueModel.java
new file mode 100644
index 0000000..2148095
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueModel.java
@@ -0,0 +1,145 @@
+/*
+ *  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.runtime.value;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.stream.Stream;
+import org.apache.polygene.api.common.MetaInfo;
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.constraint.ConstraintViolationException;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.ValueCompositeType;
+import org.apache.polygene.api.util.Classes;
+import org.apache.polygene.api.value.ValueDescriptor;
+import org.apache.polygene.runtime.composite.CompositeMethodsModel;
+import org.apache.polygene.runtime.composite.CompositeModel;
+import org.apache.polygene.runtime.composite.MixinModel;
+import org.apache.polygene.runtime.composite.MixinsModel;
+import org.apache.polygene.runtime.composite.UsesInstance;
+import org.apache.polygene.runtime.injection.InjectionContext;
+import org.apache.polygene.runtime.unitofwork.UnitOfWorkInstance;
+
+/**
+ * Model for ValueComposites
+ */
+public final class ValueModel extends CompositeModel
+    implements ValueDescriptor
+{
+    private ValueCompositeType valueType;
+
+    public ValueModel( final ModuleDescriptor module,
+                       final List<Class<?>> types,
+                       final Visibility visibility,
+                       final MetaInfo metaInfo,
+                       final MixinsModel mixinsModel,
+                       final ValueStateModel stateModel,
+                       final CompositeMethodsModel compositeMethodsModel
+    )
+    {
+        super( module, types, visibility, metaInfo, mixinsModel, stateModel, compositeMethodsModel );
+
+        valueType = new ValueCompositeType( this );
+    }
+
+    @Override
+    public ValueCompositeType valueType()
+    {
+        return valueType;
+    }
+
+    @Override
+    public ValueStateModel state()
+    {
+        return (ValueStateModel) super.state();
+    }
+
+    // This method is ONLY called by ValueBuilders
+    void checkConstraints( ValueStateInstance state )
+        throws ConstraintViolationException
+    {
+        stateModel.properties().forEach(
+            propertyModel ->
+            {
+                try
+                {
+                    propertyModel.checkConstraints( state.propertyFor( propertyModel.accessor() ).get() );
+                }
+                catch( ConstraintViolationException e )
+                {
+                    throw new ConstraintViolationException( "<builder>", propertyModel.valueType()
+                        .types(), (Member) propertyModel.accessor(), e.constraintViolations() );
+                }
+            }
+        );
+
+        // IF no UnitOfWork is active, then the Association checks shouldn't be done.
+        if( UnitOfWorkInstance.getCurrent().empty() )
+        {
+            return;
+        }
+        ( (ValueStateModel) stateModel ).associations().forEach(
+            associationModel ->
+            {
+                try
+                {
+                    associationModel.checkConstraints( state.associationFor( associationModel.accessor() ).get() );
+                }
+                catch( ConstraintViolationException e )
+                {
+                    Stream<? extends Type> types = Classes.interfacesOf( associationModel.type() );
+                    throw new ConstraintViolationException( "<builder>", types, (Member) associationModel.accessor(), e.constraintViolations() );
+                }
+            }
+        );
+
+        ( (ValueStateModel) stateModel ).manyAssociations().forEach( associationModel ->
+                                                                         associationModel.checkAssociationConstraints( state
+                                                                                                                           .manyAssociationFor( associationModel
+                                                                                                                                                    .accessor() ) )
+        );
+
+        ( (ValueStateModel) stateModel ).namedAssociations().forEach( associationModel ->
+                                                                          associationModel.checkAssociationConstraints( state
+                                                                                                                            .namedAssociationFor( associationModel
+                                                                                                                                                      .accessor() ) )
+        );
+    }
+
+    public ValueInstance newValueInstance( ValueStateInstance state )
+    {
+        Object[] mixins = mixinsModel.newMixinHolder();
+
+        ValueInstance instance = new ValueInstance( this, mixins, state );
+
+        // Instantiate all mixins
+        int i = 0;
+        InjectionContext injectionContext = new InjectionContext( instance, UsesInstance.EMPTY_USES, state );
+        for( MixinModel mixinModel : mixinsModel.mixinModels() )
+        {
+            mixins[ i++ ] = mixinModel.newInstance( injectionContext );
+        }
+
+        // Return
+        return instance;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateInstance.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateInstance.java
new file mode 100644
index 0000000..aab6597
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateInstance.java
@@ -0,0 +1,234 @@
+/*
+ *  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.runtime.value;
+
+import java.lang.reflect.AccessibleObject;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+import org.apache.polygene.api.association.AssociationStateHolder;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.value.ValueDescriptor;
+import org.apache.polygene.runtime.association.AssociationInfo;
+import org.apache.polygene.runtime.association.AssociationInstance;
+import org.apache.polygene.runtime.association.ManyAssociationInstance;
+import org.apache.polygene.runtime.association.NamedAssociationInstance;
+import org.apache.polygene.runtime.composite.StateResolver;
+import org.apache.polygene.runtime.property.PropertyInfo;
+import org.apache.polygene.runtime.property.PropertyInstance;
+import org.apache.polygene.runtime.structure.ModuleInstance;
+import org.apache.polygene.runtime.unitofwork.EntityFunction;
+
+import static java.util.stream.Collectors.toList;
+import static org.apache.polygene.api.util.Collectors.toMap;
+
+/**
+ * TODO
+ */
+public final class ValueStateInstance
+    implements AssociationStateHolder
+{
+    private final Map<AccessibleObject, PropertyInstance<?>> properties;
+    private final Map<AccessibleObject, AssociationInstance<?>> associations;
+    private final Map<AccessibleObject, ManyAssociationInstance<?>> manyAssociations;
+    private final Map<AccessibleObject, NamedAssociationInstance<?>> namedAssociations;
+
+    public ValueStateInstance( Map<AccessibleObject, PropertyInstance<?>> properties,
+                               Map<AccessibleObject, AssociationInstance<?>> associations,
+                               Map<AccessibleObject, ManyAssociationInstance<?>> manyAssociations,
+                               Map<AccessibleObject, NamedAssociationInstance<?>> namedAssociations
+    )
+    {
+        this.properties = properties;
+        this.associations = associations;
+        this.manyAssociations = manyAssociations;
+        this.namedAssociations = namedAssociations;
+    }
+
+    public ValueStateInstance( ValueDescriptor compositeModelModule,
+                               ModuleInstance currentModule,
+                               StateResolver stateResolver
+    )
+    {
+        EntityFunction entityFunction = new EntityFunction( currentModule.unitOfWorkFactory() );
+
+        ValueModel valueModel = (ValueModel) compositeModelModule;
+        this.properties = new LinkedHashMap<>();
+        valueModel.state().properties().forEach( propertyDescriptor -> {
+            PropertyInfo builderInfo = propertyDescriptor.getBuilderInfo();
+            Object value = stateResolver.getPropertyState( propertyDescriptor );
+            PropertyInstance<Object> propertyInstance = new PropertyInstance<>( builderInfo, value );
+            properties.put( propertyDescriptor.accessor(), propertyInstance );
+        } );
+
+        this.associations = new LinkedHashMap<>();
+        valueModel.state().associations().forEach( associationDescriptor -> {
+            AssociationInfo builderInfo = associationDescriptor.getBuilderInfo();
+            EntityReference value = stateResolver.getAssociationState( associationDescriptor );
+            AssociationInstance<Object> associationInstance1 = new AssociationInstance<>(
+                builderInfo,
+                entityFunction,
+                new ReferenceProperty( value ) );
+            associations.put( associationDescriptor.accessor(), associationInstance1 );
+        } );
+
+        this.manyAssociations = new LinkedHashMap<>();
+        valueModel.state().manyAssociations().forEach( associationDescriptor -> {
+            AssociationInfo builderInfo = associationDescriptor.getBuilderInfo();
+            List<EntityReference> value = stateResolver.getManyAssociationState( associationDescriptor )
+                                                       .collect( toList() );
+            ManyAssociationValueState manyAssociationState = new ManyAssociationValueState( value );
+            ManyAssociationInstance<Object> associationInstance = new ManyAssociationInstance<>(
+                builderInfo,
+                entityFunction,
+                manyAssociationState );
+            manyAssociations.put( associationDescriptor.accessor(), associationInstance );
+        } );
+
+        this.namedAssociations = new LinkedHashMap<>();
+        valueModel.state().namedAssociations().forEach( associationDescriptor -> {
+            AssociationInfo builderInfo = associationDescriptor.getBuilderInfo();
+            Map<String, EntityReference> value = stateResolver.getNamedAssociationState( associationDescriptor )
+                                                              .collect( toMap( LinkedHashMap::new ) );
+            NamedAssociationValueState namedAssociationState = new NamedAssociationValueState( value );
+            NamedAssociationInstance<Object> associationInstance = new NamedAssociationInstance<>(
+                builderInfo,
+                entityFunction,
+                namedAssociationState );
+            namedAssociations.put( associationDescriptor.accessor(), associationInstance );
+        } );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <T> PropertyInstance<T> propertyFor( AccessibleObject accessor )
+        throws IllegalArgumentException
+    {
+        PropertyInstance<T> property = (PropertyInstance<T>) properties.get( accessor );
+
+        if( property == null )
+        {
+            throw new IllegalArgumentException( "No such property:" + accessor );
+        }
+
+        return property;
+    }
+
+    @Override
+    public Stream<PropertyInstance<?>> properties()
+    {
+        return properties.values().stream();
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <T> AssociationInstance<T> associationFor( AccessibleObject accessor )
+    {
+        AssociationInstance<T> association = (AssociationInstance<T>) associations.get( accessor );
+
+        if( association == null )
+        {
+            throw new IllegalArgumentException( "No such association:" + accessor );
+        }
+
+        return association;
+    }
+
+    @Override
+    public Stream<AssociationInstance<?>> allAssociations()
+    {
+        return associations.values().stream();
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <T> ManyAssociationInstance<T> manyAssociationFor( AccessibleObject accessor )
+    {
+        ManyAssociationInstance<T> manyAssociation = (ManyAssociationInstance<T>) manyAssociations.get( accessor );
+
+        if( manyAssociation == null )
+        {
+            throw new IllegalArgumentException( "No such many-association:" + accessor );
+        }
+
+        return manyAssociation;
+    }
+
+    @Override
+    public Stream<ManyAssociationInstance<?>> allManyAssociations()
+    {
+        return manyAssociations.values().stream();
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <T> NamedAssociationInstance<T> namedAssociationFor( AccessibleObject accessor )
+    {
+        NamedAssociationInstance<T> namedAssociation = (NamedAssociationInstance<T>) namedAssociations.get( accessor );
+
+        if( namedAssociation == null )
+        {
+            throw new IllegalArgumentException( "No such named-association:" + accessor );
+        }
+
+        return namedAssociation;
+    }
+
+    @Override
+    public Stream<? extends NamedAssociationInstance<?>> allNamedAssociations()
+    {
+        return namedAssociations.values().stream();
+    }
+
+    @SuppressWarnings( "SimplifiableIfStatement" )
+    @Override
+    public boolean equals( Object obj )
+    {
+        if( !( obj instanceof ValueStateInstance ) )
+        {
+            return false;
+        }
+        ValueStateInstance state = (ValueStateInstance) obj;
+        if( !properties.equals( state.properties ) )
+        {
+            return false;
+        }
+        if( !associations.equals( state.associations ) )
+        {
+            return false;
+        }
+        if( !manyAssociations.equals( state.manyAssociations ) )
+        {
+            return false;
+        }
+        return namedAssociations.equals( state.namedAssociations );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = properties.hashCode();
+        result = 31 * result + associations.hashCode();
+        result = 31 * result + manyAssociations.hashCode();
+        result = 31 * result + namedAssociations.hashCode();
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateModel.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateModel.java
new file mode 100644
index 0000000..73c6a17
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValueStateModel.java
@@ -0,0 +1,133 @@
+/*
+ *  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.runtime.value;
+
+import java.util.stream.Stream;
+import org.apache.polygene.api.association.AssociationDescriptor;
+import org.apache.polygene.api.association.AssociationStateDescriptor;
+import org.apache.polygene.api.common.QualifiedName;
+import org.apache.polygene.api.util.HierarchicalVisitor;
+import org.apache.polygene.api.util.VisitableHierarchy;
+import org.apache.polygene.runtime.association.AssociationModel;
+import org.apache.polygene.runtime.association.AssociationsModel;
+import org.apache.polygene.runtime.association.ManyAssociationModel;
+import org.apache.polygene.runtime.association.ManyAssociationsModel;
+import org.apache.polygene.runtime.association.NamedAssociationModel;
+import org.apache.polygene.runtime.association.NamedAssociationsModel;
+import org.apache.polygene.runtime.composite.StateModel;
+import org.apache.polygene.runtime.property.PropertiesModel;
+
+/**
+ * Model for ValueComposite state.
+ */
+public final class ValueStateModel
+    extends StateModel
+    implements AssociationStateDescriptor
+{
+    private final AssociationsModel associationsModel;
+    private final ManyAssociationsModel manyAssociationsModel;
+    private final NamedAssociationsModel namedAssociationsModel;
+
+    public ValueStateModel( PropertiesModel propertiesModel,
+                            AssociationsModel associationsModel,
+                            ManyAssociationsModel manyAssociationsModel,
+                            NamedAssociationsModel namedAssociationsModel
+    )
+    {
+        super( propertiesModel );
+        this.associationsModel = associationsModel;
+        this.manyAssociationsModel = manyAssociationsModel;
+        this.namedAssociationsModel = namedAssociationsModel;
+    }
+
+    @Override
+    public AssociationDescriptor getAssociationByName( String name )
+    {
+        return associationsModel.getAssociationByName( name );
+    }
+
+    @Override
+    public AssociationDescriptor getAssociationByQualifiedName( QualifiedName name )
+    {
+        return associationsModel.getAssociationByQualifiedName( name );
+    }
+
+    @Override
+    public AssociationDescriptor getManyAssociationByName( String name )
+    {
+        return manyAssociationsModel.getManyAssociationByName( name );
+    }
+
+    @Override
+    public AssociationDescriptor getManyAssociationByQualifiedName( QualifiedName name )
+    {
+        return manyAssociationsModel.getManyAssociationByQualifiedName( name );
+    }
+
+    @Override
+    public AssociationDescriptor getNamedAssociationByName( String name )
+    {
+        return namedAssociationsModel.getNamedAssociationByName( name );
+    }
+
+    @Override
+    public AssociationDescriptor getNamedAssociationByQualifiedName( QualifiedName name )
+    {
+        return namedAssociationsModel.getNamedAssociationByQualifiedName( name );
+    }
+
+    @Override
+    public Stream<AssociationModel> associations()
+    {
+        return associationsModel.associations();
+    }
+
+    @Override
+    public Stream<ManyAssociationModel> manyAssociations()
+    {
+        return manyAssociationsModel.manyAssociations();
+    }
+
+    @Override
+    public Stream<NamedAssociationModel> namedAssociations()
+    {
+        return namedAssociationsModel.namedAssociations();
+    }
+
+    @Override
+    public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> visitor )
+        throws ThrowableType
+    {
+        if( visitor.visitEnter( this ) )
+        {
+            if( ( (VisitableHierarchy<Object, Object>) propertiesModel ).accept( visitor ) )
+            {
+                if( ( (VisitableHierarchy<AssociationsModel, AssociationModel>) associationsModel ).accept( visitor ) )
+                {
+                    if( ( (VisitableHierarchy<ManyAssociationsModel, ManyAssociationModel>) manyAssociationsModel ).accept( visitor ) )
+                    {
+                        ( (VisitableHierarchy<NamedAssociationsModel, NamedAssociationModel>) namedAssociationsModel ).accept( visitor );
+                    }
+                }
+            }
+        }
+        return visitor.visitLeave( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValuesModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValuesModel.java b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValuesModel.java
new file mode 100644
index 0000000..caa875b
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/value/ValuesModel.java
@@ -0,0 +1,68 @@
+/*
+ *  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.runtime.value;
+
+import java.util.List;
+import java.util.stream.Stream;
+import org.apache.polygene.api.util.HierarchicalVisitor;
+import org.apache.polygene.api.util.VisitableHierarchy;
+import org.apache.polygene.api.value.ValueDescriptor;
+
+/**
+ * JAVADOC
+ */
+public final class ValuesModel
+    implements VisitableHierarchy<Object, Object>
+{
+    private final List<ValueModel> valueModels;
+
+    public ValuesModel( List<ValueModel> valueModels )
+    {
+        this.valueModels = valueModels;
+    }
+
+    public Stream<ValueModel> models()
+    {
+        return valueModels.stream();
+    }
+
+    @Override
+    public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> visitor )
+        throws ThrowableType
+    {
+        if( visitor.visitEnter( this ) )
+        {
+            for( ValueModel valueModel : valueModels )
+            {
+                if( !valueModel.accept( visitor ) )
+                {
+                    break;
+                }
+            }
+        }
+        return visitor.visitLeave( this );
+    }
+
+    public Stream<? extends ValueDescriptor> stream()
+    {
+        return valueModels.stream();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
deleted file mode 100644
index 269496c..0000000
--- a/core/runtime/src/main/java/org/apache/zest/runtime/ZestRuntimeImpl.java
+++ /dev/null
@@ -1,360 +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.zest.runtime;
-
-import java.lang.reflect.InvocationHandler;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.stream.Stream;
-import org.apache.zest.api.PolygeneAPI;
-import org.apache.zest.api.association.AbstractAssociation;
-import org.apache.zest.api.association.Association;
-import org.apache.zest.api.association.AssociationDescriptor;
-import org.apache.zest.api.association.AssociationStateHolder;
-import org.apache.zest.api.association.AssociationWrapper;
-import org.apache.zest.api.association.ManyAssociation;
-import org.apache.zest.api.association.ManyAssociationWrapper;
-import org.apache.zest.api.association.NamedAssociation;
-import org.apache.zest.api.association.NamedAssociationWrapper;
-import org.apache.zest.api.composite.Composite;
-import org.apache.zest.api.composite.CompositeDescriptor;
-import org.apache.zest.api.composite.CompositeInstance;
-import org.apache.zest.api.composite.ModelDescriptor;
-import org.apache.zest.api.composite.TransientComposite;
-import org.apache.zest.api.composite.TransientDescriptor;
-import org.apache.zest.api.entity.EntityComposite;
-import org.apache.zest.api.entity.EntityDescriptor;
-import org.apache.zest.api.entity.EntityReference;
-import org.apache.zest.api.property.Property;
-import org.apache.zest.api.property.PropertyDescriptor;
-import org.apache.zest.api.property.PropertyWrapper;
-import org.apache.zest.api.property.StateHolder;
-import org.apache.zest.api.service.ServiceComposite;
-import org.apache.zest.api.service.ServiceDescriptor;
-import org.apache.zest.api.service.ServiceReference;
-import org.apache.zest.api.structure.ModuleDescriptor;
-import org.apache.zest.api.unitofwork.UnitOfWork;
-import org.apache.zest.api.value.ValueComposite;
-import org.apache.zest.api.value.ValueDescriptor;
-import org.apache.zest.bootstrap.ApplicationAssemblyFactory;
-import org.apache.zest.bootstrap.ApplicationModelFactory;
-import org.apache.zest.bootstrap.PolygeneRuntime;
-import org.apache.zest.runtime.association.AbstractAssociationInstance;
-import org.apache.zest.runtime.bootstrap.ApplicationAssemblyFactoryImpl;
-import org.apache.zest.runtime.bootstrap.ApplicationModelFactoryImpl;
-import org.apache.zest.runtime.composite.ProxyReferenceInvocationHandler;
-import org.apache.zest.runtime.composite.TransientInstance;
-import org.apache.zest.runtime.entity.EntityInstance;
-import org.apache.zest.runtime.property.PropertyInstance;
-import org.apache.zest.runtime.service.ImportedServiceReferenceInstance;
-import org.apache.zest.runtime.service.ServiceInstance;
-import org.apache.zest.runtime.service.ServiceReferenceInstance;
-import org.apache.zest.runtime.unitofwork.ModuleUnitOfWork;
-import org.apache.zest.runtime.value.ValueInstance;
-import org.apache.zest.spi.PolygeneSPI;
-import org.apache.zest.spi.entity.EntityState;
-
-import static java.lang.reflect.Proxy.getInvocationHandler;
-import static org.apache.zest.runtime.composite.TransientInstance.compositeInstanceOf;
-
-/**
- * Incarnation of Polygene.
- */
-public final class PolygeneRuntimeImpl
-    implements PolygeneSPI, PolygeneRuntime
-{
-    private final ApplicationAssemblyFactory applicationAssemblyFactory;
-    private final ApplicationModelFactory applicationModelFactory;
-
-    public PolygeneRuntimeImpl()
-    {
-        applicationAssemblyFactory = new ApplicationAssemblyFactoryImpl();
-        applicationModelFactory = new ApplicationModelFactoryImpl();
-    }
-
-    @Override
-    public ApplicationAssemblyFactory applicationAssemblyFactory()
-    {
-        return applicationAssemblyFactory;
-    }
-
-    @Override
-    public ApplicationModelFactory applicationModelFactory()
-    {
-        return applicationModelFactory;
-    }
-
-    @Override
-    public PolygeneAPI api()
-    {
-        return this;
-    }
-
-    @Override
-    public PolygeneSPI spi()
-    {
-        return this;
-    }
-
-    // API
-
-    @Override
-    @SuppressWarnings( "unchecked" )
-    public <T> T dereference( T composite )
-    {
-        InvocationHandler handler = getInvocationHandler( composite );
-        if( handler instanceof ProxyReferenceInvocationHandler )
-        {
-            return (T) ( (ProxyReferenceInvocationHandler) handler ).proxy();
-        }
-        if( handler instanceof CompositeInstance )
-        {
-            return composite;
-        }
-        return null;
-    }
-
-    @Override
-    public ModuleDescriptor moduleOf( Object compositeOrServiceReferenceOrUow )
-    {
-        if( compositeOrServiceReferenceOrUow instanceof TransientComposite )
-        {
-            TransientComposite composite = (TransientComposite) compositeOrServiceReferenceOrUow;
-            return TransientInstance.compositeInstanceOf( composite ).module();
-        }
-        else if( compositeOrServiceReferenceOrUow instanceof EntityComposite )
-        {
-            EntityComposite composite = (EntityComposite) compositeOrServiceReferenceOrUow;
-            return EntityInstance.entityInstanceOf( composite ).module();
-        }
-        else if( compositeOrServiceReferenceOrUow instanceof ValueComposite )
-        {
-            ValueComposite composite = (ValueComposite) compositeOrServiceReferenceOrUow;
-            return ValueInstance.valueInstanceOf( composite ).module();
-        }
-        else if( compositeOrServiceReferenceOrUow instanceof ServiceComposite )
-        {
-            ServiceComposite composite = (ServiceComposite) compositeOrServiceReferenceOrUow;
-            InvocationHandler handler = getInvocationHandler( composite );
-            if( handler instanceof ServiceInstance )
-            {
-                return ( (ServiceInstance) handler ).module();
-            }
-            return ( (ServiceReferenceInstance.ServiceInvocationHandler) handler ).module();
-        }
-        else if( compositeOrServiceReferenceOrUow instanceof UnitOfWork )
-        {
-            ModuleUnitOfWork unitOfWork = (ModuleUnitOfWork) compositeOrServiceReferenceOrUow;
-            return unitOfWork.module();
-        }
-        else if( compositeOrServiceReferenceOrUow instanceof ServiceReferenceInstance )
-        {
-            ServiceReferenceInstance<?> reference = (ServiceReferenceInstance<?>) compositeOrServiceReferenceOrUow;
-            return reference.module();
-        }
-        else if( compositeOrServiceReferenceOrUow instanceof ImportedServiceReferenceInstance )
-        {
-            ImportedServiceReferenceInstance<?> importedServiceReference
-                = (ImportedServiceReferenceInstance<?>) compositeOrServiceReferenceOrUow;
-            return importedServiceReference.module();
-        }
-        throw new IllegalArgumentException( "Wrong type. Must be one of "
-                                            + Arrays.asList( TransientComposite.class, ValueComposite.class,
-                                                             ServiceComposite.class, ServiceReference.class,
-                                                             UnitOfWork.class ) );
-    }
-
-    @Override
-    public ModelDescriptor modelDescriptorFor( Object compositeOrServiceReference )
-    {
-        if( compositeOrServiceReference instanceof TransientComposite )
-        {
-            TransientComposite composite = (TransientComposite) compositeOrServiceReference;
-            return TransientInstance.compositeInstanceOf( composite ).descriptor();
-        }
-        else if( compositeOrServiceReference instanceof EntityComposite )
-        {
-            EntityComposite composite = (EntityComposite) compositeOrServiceReference;
-            return EntityInstance.entityInstanceOf( composite ).descriptor();
-        }
-        else if( compositeOrServiceReference instanceof ValueComposite )
-        {
-            ValueComposite composite = (ValueComposite) compositeOrServiceReference;
-            return ValueInstance.valueInstanceOf( composite ).descriptor();
-        }
-        else if( compositeOrServiceReference instanceof ServiceComposite )
-        {
-            ServiceComposite composite = (ServiceComposite) compositeOrServiceReference;
-            InvocationHandler handler = getInvocationHandler( composite );
-            if( handler instanceof ServiceInstance )
-            {
-                return ( (ServiceInstance) handler ).descriptor();
-            }
-            return ( (ServiceReferenceInstance.ServiceInvocationHandler) handler ).descriptor();
-        }
-        else if( compositeOrServiceReference instanceof ServiceReferenceInstance )
-        {
-            ServiceReferenceInstance<?> reference = (ServiceReferenceInstance<?>) compositeOrServiceReference;
-            return reference.serviceDescriptor();
-        }
-        else if( compositeOrServiceReference instanceof ImportedServiceReferenceInstance )
-        {
-            ImportedServiceReferenceInstance<?> importedServiceReference
-                = (ImportedServiceReferenceInstance<?>) compositeOrServiceReference;
-            return importedServiceReference.serviceDescriptor();
-        }
-        throw new IllegalArgumentException( "Wrong type. Must be one of "
-                                            + Arrays.asList( TransientComposite.class, ValueComposite.class,
-                                                             ServiceComposite.class, ServiceReference.class ) );
-    }
-
-    @Override
-    public CompositeDescriptor compositeDescriptorFor( Object compositeOrServiceReference )
-    {
-        return (CompositeDescriptor) modelDescriptorFor( compositeOrServiceReference );
-    }
-
-    // Descriptors
-
-    @Override
-    public TransientDescriptor transientDescriptorFor( Object transsient )
-    {
-        if( transsient instanceof TransientComposite )
-        {
-            TransientInstance transientInstance = compositeInstanceOf( (Composite) transsient );
-            return (TransientDescriptor) transientInstance.descriptor();
-        }
-        throw new IllegalArgumentException( "Wrong type. Must be subtype of " + TransientComposite.class );
-    }
-
-    @Override
-    public StateHolder stateOf( TransientComposite composite )
-    {
-        return TransientInstance.compositeInstanceOf( composite ).state();
-    }
-
-    @Override
-    public EntityDescriptor entityDescriptorFor( Object entity )
-    {
-        if( entity instanceof EntityComposite )
-        {
-            EntityInstance entityInstance = (EntityInstance) getInvocationHandler( entity );
-            return entityInstance.entityModel();
-        }
-        throw new IllegalArgumentException( "Wrong type. Must be subtype of " + EntityComposite.class );
-    }
-
-    @Override
-    public AssociationStateHolder stateOf( EntityComposite composite )
-    {
-        return EntityInstance.entityInstanceOf( composite ).state();
-    }
-
-    @Override
-    public ValueDescriptor valueDescriptorFor( Object value )
-    {
-        if( value instanceof ValueComposite )
-        {
-            ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value );
-            return valueInstance.descriptor();
-        }
-        throw new IllegalArgumentException( "Wrong type. Must be subtype of " + ValueComposite.class );
-    }
-
-    @Override
-    public AssociationStateHolder stateOf( ValueComposite composite )
-    {
-        return ValueInstance.valueInstanceOf( composite ).state();
-    }
-
-    @Override
-    public ServiceDescriptor serviceDescriptorFor( Object service )
-    {
-        if( service instanceof ServiceReferenceInstance )
-        {
-            ServiceReferenceInstance<?> ref = (ServiceReferenceInstance<?>) service;
-            return ref.serviceDescriptor();
-        }
-        if( service instanceof ServiceComposite )
-        {
-            ServiceComposite composite = (ServiceComposite) service;
-            return (ServiceDescriptor) ServiceInstance.serviceInstanceOf( composite ).descriptor();
-        }
-        throw new IllegalArgumentException( "Wrong type. Must be subtype of "
-                                            + ServiceComposite.class + " or " + ServiceReference.class );
-    }
-
-    @Override
-    public PropertyDescriptor propertyDescriptorFor( Property<?> property )
-    {
-        while( property instanceof PropertyWrapper )
-        {
-            property = ( (PropertyWrapper) property ).next();
-        }
-
-        return (PropertyDescriptor) ( (PropertyInstance<?>) property ).propertyInfo();
-    }
-
-    @Override
-    public AssociationDescriptor associationDescriptorFor( AbstractAssociation association )
-    {
-        while( association instanceof AssociationWrapper )
-        {
-            association = ( (AssociationWrapper) association ).next();
-        }
-
-        while( association instanceof ManyAssociationWrapper )
-        {
-            association = ( (ManyAssociationWrapper) association ).next();
-        }
-
-        while( association instanceof NamedAssociationWrapper )
-        {
-            association = ( (NamedAssociationWrapper) association ).next();
-        }
-
-        return (AssociationDescriptor) ( (AbstractAssociationInstance) association ).associationInfo();
-    }
-
-    // SPI
-    @Override
-    public EntityState entityStateOf( EntityComposite composite )
-    {
-        return EntityInstance.entityInstanceOf( composite ).entityState();
-    }
-
-    @Override
-    public EntityReference entityReferenceOf( Association<?> assoc )
-    {
-        return assoc.reference();
-    }
-
-    @Override
-    public Stream<EntityReference> entityReferencesOf( ManyAssociation<?> assoc )
-    {
-        return assoc.references();
-    }
-
-    @Override
-    public Stream<Map.Entry<String, EntityReference>> entityReferencesOf( NamedAssociation<?> assoc )
-    {
-        return assoc.references();
-    }
-}