polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject [8/9] zest-java git commit: ZEST-132, ZEST-97 UnitOfWorkFactory as a customizable Service UnitOfWork as a customizable Transient Class can be a Transient directly, with itself as both the Composite Type and the Mixin. SideEffects declarations
Date Wed, 16 Dec 2015 06:17:45 GMT
http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
index bb9aa65..4bf431f 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java
@@ -23,9 +23,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Stack;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
@@ -42,7 +40,6 @@ import org.apache.zest.api.composite.ModelDescriptor;
 import org.apache.zest.api.composite.NoSuchTransientException;
 import org.apache.zest.api.composite.TransientBuilder;
 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.entity.IdentityGenerator;
@@ -58,10 +55,8 @@ import org.apache.zest.api.service.NoSuchServiceException;
 import org.apache.zest.api.service.ServiceDescriptor;
 import org.apache.zest.api.service.ServiceReference;
 import org.apache.zest.api.structure.Module;
-import org.apache.zest.api.unitofwork.UnitOfWork;
 import org.apache.zest.api.unitofwork.UnitOfWorkException;
 import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
-import org.apache.zest.api.usecase.Usecase;
 import org.apache.zest.api.util.NullArgumentException;
 import org.apache.zest.api.value.NoSuchValueException;
 import org.apache.zest.api.value.ValueBuilder;
@@ -73,13 +68,10 @@ import org.apache.zest.runtime.activation.ActivationDelegate;
 import org.apache.zest.runtime.composite.FunctionStateResolver;
 import org.apache.zest.runtime.composite.StateResolver;
 import org.apache.zest.runtime.composite.TransientBuilderInstance;
-import org.apache.zest.runtime.composite.TransientModel;
 import org.apache.zest.runtime.composite.TransientStateInstance;
 import org.apache.zest.runtime.composite.TransientsModel;
 import org.apache.zest.runtime.composite.UsesInstance;
 import org.apache.zest.runtime.entity.EntitiesModel;
-import org.apache.zest.runtime.entity.EntityInstance;
-import org.apache.zest.runtime.entity.EntityModel;
 import org.apache.zest.runtime.injection.InjectionContext;
 import org.apache.zest.runtime.object.ObjectModel;
 import org.apache.zest.runtime.object.ObjectsModel;
@@ -90,21 +82,18 @@ import org.apache.zest.runtime.service.ImportedServicesInstance;
 import org.apache.zest.runtime.service.ImportedServicesModel;
 import org.apache.zest.runtime.service.ServicesInstance;
 import org.apache.zest.runtime.service.ServicesModel;
-import org.apache.zest.runtime.unitofwork.UnitOfWorkInstance;
 import org.apache.zest.runtime.value.ValueBuilderInstance;
 import org.apache.zest.runtime.value.ValueBuilderWithPrototype;
 import org.apache.zest.runtime.value.ValueBuilderWithState;
 import org.apache.zest.runtime.value.ValueInstance;
-import org.apache.zest.runtime.value.ValueModel;
 import org.apache.zest.runtime.value.ValuesModel;
 import org.apache.zest.spi.entitystore.EntityStore;
 import org.apache.zest.spi.metrics.MetricsProviderAdapter;
-import org.apache.zest.spi.module.ModelModule;
 import org.apache.zest.spi.module.ModuleSpi;
+import org.apache.zest.spi.structure.ModelModule;
 import org.apache.zest.valueserialization.orgjson.OrgJsonValueSerialization;
 
 import static java.util.stream.Stream.concat;
-import static org.apache.zest.api.util.Classes.RAW_CLASS;
 import static org.apache.zest.api.util.Classes.modelTypeSpecification;
 import static org.apache.zest.functional.Iterables.iterable;
 import static org.apache.zest.runtime.legacy.Specifications.translate;
@@ -126,15 +115,15 @@ public class ModuleInstance
     private final ImportedServicesInstance importedServices;
     // Eager instance objects
     private final ActivationDelegate activation;
-    private final TypeLookup typeLookup;
+    private final TypeLookupImpl typeLookup;
     private final QueryBuilderFactory queryBuilderFactory;
     private final ClassLoader classLoader;
-    private final EntityFunction entityFunction;
     // Lazy assigned on accessors
     private EntityStore store;
     private IdentityGenerator generator;
     private ValueSerialization valueSerialization;
     private MetricsProvider metrics;
+    private UnitOfWorkFactory uowf;
 
     @SuppressWarnings( "LeakingThisInConstructor" )
     public ModuleInstance( ModuleModel moduleModel, LayerInstance layerInstance, TransientsModel transientsModel,
@@ -147,17 +136,16 @@ public class ModuleInstance
         layer = layerInstance;
         transients = transientsModel;
         values = valuesModel;
-        objects = objectsModel;
         entities = entitiesModel;
         services = servicesModel.newInstance( this );
+        objects = objectsModel;
         importedServices = importedServicesModel.newInstance( this );
 
         // Eager instance objects
         activation = new ActivationDelegate( this );
-        typeLookup = new TypeLookup( this );
+        typeLookup = new TypeLookupImpl( this );
         queryBuilderFactory = new QueryBuilderFactoryImpl( this );
         classLoader = new ModuleClassLoader( this, Thread.currentThread().getContextClassLoader() );
-        entityFunction = new EntityFunction( this );
 
         // Activation
         services.registerActivationEventListener( activation );
@@ -316,7 +304,7 @@ public class ModuleInstance
         }
 
         InjectionContext injectionContext = new InjectionContext( modelModule.module(), UsesInstance.EMPTY_USES.use( uses ) );
-        return mixinType.cast( ((ObjectModel) modelModule.model()).newInstance( injectionContext ) );
+        return mixinType.cast( ( (ObjectModel) modelModule.model() ).newInstance( injectionContext ) );
     }
 
     @Override
@@ -332,7 +320,7 @@ public class ModuleInstance
         }
 
         InjectionContext injectionContext = new InjectionContext( modelModule.module(), UsesInstance.EMPTY_USES.use( uses ) );
-        ((ObjectModel) modelModule.model()).inject( injectionContext, instance );
+        ( (ObjectModel) modelModule.model() ).inject( injectionContext, instance );
     }
 
     // Implementation of TransientBuilderFactory
@@ -352,7 +340,7 @@ public class ModuleInstance
         modelModule.model().state().properties().forEach(
             propertyModel ->
             {
-                Property<?> property = new PropertyInstance<>( ((PropertyModel) propertyModel).getBuilderInfo(),
+                Property<?> property = new PropertyInstance<>( ( (PropertyModel) propertyModel ).getBuilderInfo(),
                                                                propertyModel.initialValue( modelModule.module() ) );
                 properties.put( propertyModel.accessor(), property );
             } );
@@ -495,57 +483,6 @@ public class ModuleInstance
         }
     }
 
-    // Implementation of UnitOfWorkFactory
-    @Override
-    public UnitOfWork newUnitOfWork()
-    {
-        return newUnitOfWork( Usecase.DEFAULT );
-    }
-
-    @Override
-    public UnitOfWork newUnitOfWork( long currentTime )
-    {
-        return newUnitOfWork( Usecase.DEFAULT, currentTime );
-    }
-
-    @Override
-    public UnitOfWork newUnitOfWork( Usecase usecase )
-    {
-        return newUnitOfWork( usecase == null ? Usecase.DEFAULT : usecase, System.currentTimeMillis() );
-    }
-
-    @Override
-    public UnitOfWork newUnitOfWork( Usecase usecase, long currentTime )
-    {
-        UnitOfWorkInstance unitOfWorkInstance = new UnitOfWorkInstance( usecase, currentTime, metricsProvider() );
-        return new ModuleUnitOfWork( ModuleInstance.this, unitOfWorkInstance );
-    }
-
-    @Override
-    public boolean isUnitOfWorkActive()
-    {
-        Stack<UnitOfWorkInstance> stack = UnitOfWorkInstance.getCurrent();
-        return !stack.isEmpty();
-    }
-
-    @Override
-    public UnitOfWork currentUnitOfWork()
-    {
-        Stack<UnitOfWorkInstance> stack = UnitOfWorkInstance.getCurrent();
-        if( stack.size() == 0 )
-        {
-            throw new IllegalStateException( "No current UnitOfWork active" );
-        }
-        return new ModuleUnitOfWork( ModuleInstance.this, stack.peek() );
-    }
-
-    @Override
-    public UnitOfWork getUnitOfWork( EntityComposite entity )
-    {
-        EntityInstance instance = EntityInstance.entityInstanceOf( entity );
-        return instance.unitOfWork();
-    }
-
     // Implementation of QueryBuilderFactory
     @Override
     public <T> QueryBuilder<T> newQueryBuilder( final Class<T> resultType )
@@ -617,42 +554,24 @@ public class ModuleInstance
         return layer;
     }
 
-    public TypeLookup typeLookup()
+    @Override
+    public TypeLookupImpl typeLookup()
     {
         return typeLookup;
     }
 
-    public BiFunction<EntityReference, Type, Object> getEntityFunction()
-    {
-        return entityFunction;
-    }
-
-    private static class EntityFunction
-        implements BiFunction<EntityReference, Type, Object>
-    {
-
-        private final UnitOfWorkFactory uowf;
-
-        private EntityFunction( UnitOfWorkFactory uowf )
-        {
-            this.uowf = uowf;
-        }
-
-        @Override
-        public Object apply( EntityReference entityReference, Type type )
-        {
-            return uowf.currentUnitOfWork().get( RAW_CLASS.apply( type ), entityReference.identity() );
-        }
-    }
-
     public EntityStore entityStore()
     {
         synchronized( this )
         {
             if( store == null )
             {
-                ServiceReference<EntityStore> service = findService( EntityStore.class );
-                if( service == null )
+                ServiceReference<EntityStore> service = null;
+                try
+                {
+                    service = findService( EntityStore.class );
+                }
+                catch( NoSuchServiceException e )
                 {
                     throw new UnitOfWorkException( "No EntityStore service available in module " + name() );
                 }
@@ -662,6 +581,27 @@ public class ModuleInstance
         return store;
     }
 
+    public UnitOfWorkFactory unitOfWorkFactory()
+    {
+        synchronized( this )
+        {
+            if( uowf == null )
+            {
+                ServiceReference<UnitOfWorkFactory> service = null;
+                try
+                {
+                    service = findService( UnitOfWorkFactory.class );
+                }
+                catch( NoSuchServiceException e )
+                {
+                    throw new UnitOfWorkException( "No UnitOfWorkFactory service available in module " + name() );
+                }
+                uowf = service.get();
+            }
+        }
+        return uowf;
+    }
+
     public IdentityGenerator identityGenerator()
     {
         synchronized( this )
@@ -695,7 +635,7 @@ public class ModuleInstance
         return valueSerialization;
     }
 
-    /* package */ MetricsProvider metricsProvider()
+    public MetricsProvider metricsProvider()
     {
         synchronized( this )
         {

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleUnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleUnitOfWork.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleUnitOfWork.java
deleted file mode 100755
index b5303d5..0000000
--- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleUnitOfWork.java
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (c) 2009, Rickard Öberg. All Rights Reserved.
- * Copyright (c) 2013-2015, Niclas Hedhman. All Rights Reserved.
- * Copyright (c) 2013-2015, 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.apache.zest.runtime.structure;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import org.apache.zest.api.association.AssociationDescriptor;
-import org.apache.zest.api.association.AssociationStateHolder;
-import org.apache.zest.api.common.QualifiedName;
-import org.apache.zest.api.composite.Composite;
-import org.apache.zest.api.entity.EntityBuilder;
-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.entity.Identity;
-import org.apache.zest.api.entity.IdentityGenerator;
-import org.apache.zest.api.entity.LifecycleException;
-import org.apache.zest.api.property.Property;
-import org.apache.zest.api.property.PropertyDescriptor;
-import org.apache.zest.api.property.StateHolder;
-import org.apache.zest.api.query.Query;
-import org.apache.zest.api.query.QueryBuilder;
-import org.apache.zest.api.query.QueryExecutionException;
-import org.apache.zest.api.query.grammar.OrderBy;
-import org.apache.zest.api.service.NoSuchServiceException;
-import org.apache.zest.api.unitofwork.ConcurrentEntityModificationException;
-import org.apache.zest.api.unitofwork.EntityTypeNotFoundException;
-import org.apache.zest.api.unitofwork.NoSuchEntityException;
-import org.apache.zest.api.unitofwork.UnitOfWork;
-import org.apache.zest.api.unitofwork.UnitOfWorkCallback;
-import org.apache.zest.api.unitofwork.UnitOfWorkCompletionException;
-import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
-import org.apache.zest.api.usecase.Usecase;
-import org.apache.zest.api.util.NullArgumentException;
-import org.apache.zest.api.value.ValueBuilder;
-import org.apache.zest.api.value.ValueComposite;
-import org.apache.zest.functional.Iterables;
-import org.apache.zest.runtime.association.AssociationInstance;
-import org.apache.zest.runtime.association.ManyAssociationInstance;
-import org.apache.zest.runtime.association.NamedAssociationInstance;
-import org.apache.zest.runtime.composite.FunctionStateResolver;
-import org.apache.zest.runtime.entity.EntityInstance;
-import org.apache.zest.runtime.entity.EntityModel;
-import org.apache.zest.runtime.property.PropertyModel;
-import org.apache.zest.runtime.unitofwork.EntityBuilderInstance;
-import org.apache.zest.runtime.unitofwork.UnitOfWorkInstance;
-import org.apache.zest.runtime.value.ValueInstance;
-import org.apache.zest.spi.entity.EntityState;
-import org.apache.zest.spi.entity.EntityStatus;
-import org.apache.zest.spi.entity.NamedAssociationState;
-import org.apache.zest.spi.entitystore.EntityStore;
-import org.apache.zest.spi.module.ModelModule;
-import org.apache.zest.spi.query.EntityFinder;
-import org.apache.zest.spi.query.EntityFinderException;
-import org.apache.zest.spi.query.QueryBuilderSPI;
-import org.apache.zest.spi.query.QuerySource;
-
-import static org.apache.zest.api.entity.EntityReference.parseEntityReference;
-
-/**
- * JAVADOC
- */
-public class ModuleUnitOfWork
-    implements UnitOfWork
-{
-    private static final QualifiedName IDENTITY_STATE_NAME;
-
-    static
-    {
-        try
-        {
-            IDENTITY_STATE_NAME = QualifiedName.fromAccessor( Identity.class.getMethod( "identity" ) );
-        }
-        catch( NoSuchMethodException e )
-        {
-            throw new InternalError( "Zest Core Runtime codebase is corrupted. Contact Zest team: ModuleUnitOfWork" );
-        }
-    }
-
-    private final UnitOfWorkInstance uow;
-    private final ModuleInstance module;
-
-    ModuleUnitOfWork( ModuleInstance module, UnitOfWorkInstance uow )
-    {
-        this.module = module;
-        this.uow = uow;
-    }
-
-    public ModuleInstance module()
-    {
-        return module;
-    }
-
-    public UnitOfWorkInstance instance()
-    {
-        return uow;
-    }
-
-    @Override
-    public UnitOfWorkFactory unitOfWorkFactory()
-    {
-        return module;
-    }
-
-    @Override
-    public long currentTime()
-    {
-        return uow.currentTime();
-    }
-
-    @Override
-    public Usecase usecase()
-    {
-        return uow.usecase();
-    }
-
-    @Override
-    public <T> T metaInfo( Class<T> infoType )
-    {
-        return uow.metaInfo().get( infoType );
-    }
-
-    @Override
-    public void setMetaInfo( Object metaInfo )
-    {
-        uow.metaInfo().set( metaInfo );
-    }
-
-    @Override
-    @SuppressWarnings( { "raw", "unchecked" } )
-    public <T> Query<T> newQuery( QueryBuilder<T> queryBuilder )
-    {
-        QueryBuilderSPI queryBuilderSPI = (QueryBuilderSPI) queryBuilder;
-
-        return queryBuilderSPI.newQuery( new UoWQuerySource( this ) );
-    }
-
-    @Override
-    public <T> T newEntity( Class<T> type )
-        throws EntityTypeNotFoundException, LifecycleException
-    {
-        return newEntity( type, null );
-    }
-
-    @Override
-    public <T> T newEntity( Class<T> type, String identity )
-        throws EntityTypeNotFoundException, LifecycleException
-    {
-        return newEntityBuilder( type, identity ).newInstance();
-    }
-
-    @Override
-    public <T> EntityBuilder<T> newEntityBuilder( Class<T> type )
-        throws EntityTypeNotFoundException
-    {
-        return newEntityBuilder( type, null );
-    }
-
-    @Override
-    public <T> EntityBuilder<T> newEntityBuilder( Class<T> type, String identity )
-        throws EntityTypeNotFoundException
-    {
-        ModelModule<EntityDescriptor> model = module.typeLookup().lookupEntityModel( type );
-
-        if( model == null )
-        {
-            throw new EntityTypeNotFoundException( type.getName(),
-                                                   module.name(),
-                                                   module.findVisibleEntityTypes().map( ModelModule.toStringFunction )
-            );
-        }
-
-        EntityStore entityStore = model.module().entityStore();
-
-        // Generate id if necessary
-        if( identity == null )
-        {
-            IdentityGenerator idGen = model.module().identityGenerator();
-            if( idGen == null )
-            {
-                throw new NoSuchServiceException( IdentityGenerator.class.getName(), model.module().name() );
-            }
-            identity = idGen.generate( model.model().types().findFirst().orElse( null ) );
-        }
-        EntityBuilder<T> builder;
-
-        builder = new EntityBuilderInstance<>( model,
-                                               this,
-                                               uow.getEntityStoreUnitOfWork( entityStore ),
-                                               identity );
-        return builder;
-    }
-
-    @Override
-    public <T> EntityBuilder<T> newEntityBuilderWithState(
-        Class<T> type,
-        Function<PropertyDescriptor, Object> propertyFunction,
-        Function<AssociationDescriptor, EntityReference> associationFunction,
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
-    )
-        throws EntityTypeNotFoundException
-    {
-        return newEntityBuilderWithState( type, null,
-                                          propertyFunction,
-                                          associationFunction,
-                                          manyAssociationFunction,
-                                          namedAssociationFunction );
-    }
-
-    @Override
-    public <T> EntityBuilder<T> newEntityBuilderWithState(
-        Class<T> type, String identity,
-        Function<PropertyDescriptor, Object> propertyFunction,
-        Function<AssociationDescriptor, EntityReference> associationFunction,
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
-    )
-        throws EntityTypeNotFoundException
-    {
-        NullArgumentException.validateNotNull( "propertyFunction", propertyFunction );
-        NullArgumentException.validateNotNull( "associationFunction", associationFunction );
-        NullArgumentException.validateNotNull( "manyAssociationFunction", manyAssociationFunction );
-        NullArgumentException.validateNotNull( "namedAssociationFunction", namedAssociationFunction );
-
-        ModelModule<EntityDescriptor> model = module.typeLookup().lookupEntityModel( type );
-
-        if( model == null )
-        {
-            throw new EntityTypeNotFoundException( type.getName(),
-                                                   module.name(),
-                                                   module.findVisibleEntityTypes().map( ModelModule.toStringFunction )
-            );
-        }
-
-        EntityStore entityStore = model.module().entityStore();
-
-        FunctionStateResolver stateResolver = new FunctionStateResolver(
-            propertyFunction, associationFunction, manyAssociationFunction, namedAssociationFunction
-        );
-
-        if( identity == null )
-        {
-            // Use identity from StateResolver if available
-            PropertyModel identityModel = (PropertyModel) model.model().state().findPropertyModelByQualifiedName( IDENTITY_STATE_NAME );
-            identity = (String) stateResolver.getPropertyState( identityModel );
-            if( identity == null )
-            {
-                // Generate identity
-                IdentityGenerator idGen = model.module().identityGenerator();
-                if( idGen == null )
-                {
-                    throw new NoSuchServiceException( IdentityGenerator.class.getName(), model.module().name() );
-                }
-                identity = idGen.generate( model.model().types().findFirst().orElse( null ));
-            }
-        }
-
-        return new EntityBuilderInstance<>( model,
-                                            this,
-                                            uow.getEntityStoreUnitOfWork( entityStore ),
-                                            identity,
-                                            stateResolver );
-    }
-
-    @Override
-    public <T> T get( Class<T> type, String identity )
-        throws EntityTypeNotFoundException, NoSuchEntityException
-    {
-        Iterable<ModelModule<EntityDescriptor>> models = module.typeLookup().lookupEntityModels( type );
-
-        if( !models.iterator().hasNext() )
-        {
-            throw new EntityTypeNotFoundException( type.getName(),
-                                                   module.name(),
-                                                   module.findVisibleEntityTypes().map( ModelModule.toStringFunction )
-            );
-        }
-
-        return uow.get( parseEntityReference( identity ), this, models, type );
-    }
-
-    @Override
-    @SuppressWarnings( "unchecked" )
-    public <T> T get( T entity )
-        throws EntityTypeNotFoundException
-    {
-        EntityComposite entityComposite = (EntityComposite) entity;
-        EntityInstance compositeInstance = EntityInstance.entityInstanceOf( entityComposite );
-        ModelModule<EntityDescriptor> model = new ModelModule<>( compositeInstance.module(), compositeInstance.entityModel() );
-        Class<T> type = (Class<T>) compositeInstance.types().findFirst().orElse( null );
-        return uow.get( compositeInstance.identity(), this, Collections.singletonList( model ), type );
-    }
-
-    @Override
-    public void remove( Object entity )
-        throws LifecycleException
-    {
-        uow.checkOpen();
-
-        EntityComposite entityComposite = (EntityComposite) entity;
-
-        EntityInstance compositeInstance = EntityInstance.entityInstanceOf( entityComposite );
-
-        if( compositeInstance.status() == EntityStatus.NEW )
-        {
-            compositeInstance.remove( this );
-            uow.remove( compositeInstance.identity() );
-        }
-        else if( compositeInstance.status() == EntityStatus.LOADED || compositeInstance.status() == EntityStatus.UPDATED )
-        {
-            compositeInstance.remove( this );
-        }
-        else
-        {
-            throw new NoSuchEntityException( compositeInstance.identity(), compositeInstance.types(), usecase() );
-        }
-    }
-
-    @SuppressWarnings( "DuplicateThrows" )
-    @Override
-    public void complete()
-        throws UnitOfWorkCompletionException, ConcurrentEntityModificationException
-    {
-        uow.complete();
-    }
-
-    @Override
-    public void discard()
-    {
-        uow.discard();
-    }
-
-    @Override
-    public void close()
-    {
-        discard();
-    }
-
-    @Override
-    public boolean isOpen()
-    {
-        return uow.isOpen();
-    }
-
-    @Override
-    public boolean isPaused()
-    {
-        return uow.isPaused();
-    }
-
-    @Override
-    public void pause()
-    {
-        uow.pause();
-    }
-
-    @Override
-    public void resume()
-    {
-        uow.resume();
-    }
-
-    @Override
-    public void addUnitOfWorkCallback( UnitOfWorkCallback callback )
-    {
-        uow.addUnitOfWorkCallback( callback );
-    }
-
-    @Override
-    public void removeUnitOfWorkCallback( UnitOfWorkCallback callback )
-    {
-        uow.removeUnitOfWorkCallback( callback );
-    }
-
-    @Override
-    public boolean equals( Object o )
-    {
-        if( this == o )
-        {
-            return true;
-        }
-        if( o == null || getClass() != o.getClass() )
-        {
-            return false;
-        }
-
-        ModuleUnitOfWork that = (ModuleUnitOfWork) o;
-
-        return uow.equals( that.uow );
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return uow.hashCode();
-    }
-
-    @Override
-    public String toString()
-    {
-        return uow.toString();
-    }
-
-    public void addEntity( EntityInstance instance )
-    {
-        uow.addEntity( instance );
-    }
-
-    @Override
-    public <T extends Identity> T toValue( Class<T> primaryType, T entityComposite )
-    {
-        Function<PropertyDescriptor, Object> propertyFunction = new ToValuePropertyMappingFunction( entityComposite );
-        Function<AssociationDescriptor, EntityReference> assocationFunction = new ToValueAssociationMappingFunction<>( entityComposite );
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssocFunction = new ToValueManyAssociationMappingFunction<>( entityComposite );
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssocFunction = new ToValueNameAssociationMappingFunction<>( entityComposite );
-
-        @SuppressWarnings( "unchecked" )
-        ValueBuilder<T> builder = module().newValueBuilderWithState(
-            primaryType, propertyFunction, assocationFunction, manyAssocFunction, namedAssocFunction );
-        return builder.newInstance();
-    }
-
-    @Override
-    public <T extends Identity> T toEntity( Class<T> primaryType, T valueComposite )
-    {
-        Function<PropertyDescriptor, Object> propertyFunction = new ToEntityPropertyMappingFunction<>( valueComposite );
-        Function<AssociationDescriptor, EntityReference> assocationFunction = new ToEntityAssociationMappingFunction<>( valueComposite );
-        Function<AssociationDescriptor, Iterable<EntityReference>> manyAssocFunction = new ToEntityManyAssociationMappingFunction<>( valueComposite );
-        Function<AssociationDescriptor, Map<String, EntityReference>> namedAssocFunction = new ToEntityNameAssociationMappingFunction<>( valueComposite );
-
-        String identity = valueComposite.identity().get();
-        try
-        {
-            T entity = get( primaryType, identity );
-            // If successful, then this entity is to by modified.
-            EntityInstance instance = EntityInstance.entityInstanceOf( (EntityComposite) entity );
-            EntityState state = instance.entityState();
-            FunctionStateResolver stateResolver = new FunctionStateResolver( propertyFunction,
-                                                                             assocationFunction,
-                                                                             manyAssocFunction,
-                                                                             namedAssocFunction );
-            EntityModel model = (EntityModel) EntityInstance.entityInstanceOf( (EntityComposite) entity ).descriptor();
-            stateResolver.populateState( model, state );
-            return entity;
-        }
-        catch( NoSuchEntityException e )
-        {
-            EntityBuilder<T> entityBuilder = newEntityBuilderWithState( primaryType,
-                                                                        identity,
-                                                                        propertyFunction,
-                                                                        assocationFunction,
-                                                                        manyAssocFunction,
-                                                                        namedAssocFunction );
-            return entityBuilder.newInstance();
-        }
-    }
-
-    private static class UoWQuerySource implements QuerySource
-    {
-        private final ModuleUnitOfWork moduleUnitOfWork;
-
-        private UoWQuerySource( ModuleUnitOfWork moduleUnitOfWork )
-        {
-            this.moduleUnitOfWork = moduleUnitOfWork;
-        }
-
-        @Override
-        public <T> T find( Class<T> resultType,
-                           Predicate<Composite> whereClause,
-                           Iterable<OrderBy> orderBySegments,
-                           Integer firstResult,
-                           Integer maxResults,
-                           Map<String, Object> variables
-        )
-        {
-            final EntityFinder entityFinder = moduleUnitOfWork.module().findService( EntityFinder.class ).get();
-
-            try
-            {
-                final EntityReference foundEntity = entityFinder.findEntity( resultType, whereClause, variables == null ? Collections
-                    .<String, Object>emptyMap() : variables );
-                if( foundEntity != null )
-                {
-                    try
-                    {
-                        return moduleUnitOfWork.get( resultType, foundEntity.identity() );
-                    }
-                    catch( NoSuchEntityException e )
-                    {
-                        return null; // Index is out of sync - entity has been removed
-                    }
-                }
-                // No entity was found
-                return null;
-            }
-            catch( EntityFinderException e )
-            {
-                throw new QueryExecutionException( "Finder caused exception", e );
-            }
-        }
-
-        @Override
-        public <T> long count( Class<T> resultType,
-                               Predicate<Composite> whereClause,
-                               Iterable<OrderBy> orderBySegments,
-                               Integer firstResult,
-                               Integer maxResults,
-                               Map<String, Object> variables
-        )
-        {
-            final EntityFinder entityFinder = moduleUnitOfWork.module().findService( EntityFinder.class ).get();
-
-            try
-            {
-                return entityFinder.countEntities( resultType, whereClause, variables == null ? Collections.<String, Object>emptyMap() : variables );
-            }
-            catch( EntityFinderException e )
-            {
-                e.printStackTrace();
-                return 0;
-            }
-        }
-
-        @Override
-        public <T> Iterator<T> iterator( final Class<T> resultType,
-                                         Predicate<Composite> whereClause,
-                                         Iterable<OrderBy> orderBySegments,
-                                         Integer firstResult,
-                                         Integer maxResults,
-                                         Map<String, Object> variables
-        )
-        {
-            final EntityFinder entityFinder = moduleUnitOfWork.module().findService( EntityFinder.class ).get();
-
-            try
-            {
-                final Iterator<EntityReference> foundEntities = entityFinder.findEntities( resultType,
-                                                                                           whereClause,
-                                                                                           Iterables.toArray( OrderBy.class, orderBySegments ),
-                                                                                           firstResult,
-                                                                                           maxResults,
-                                                                                           variables == null ? Collections
-                                                                                               .<String, Object>emptyMap() : variables )
-                    .iterator();
-
-                return new Iterator<T>()
-                {
-                    @Override
-                    public boolean hasNext()
-                    {
-                        return foundEntities.hasNext();
-                    }
-
-                    @Override
-                    public T next()
-                    {
-                        final EntityReference foundEntity = foundEntities.next();
-                        try
-                        {
-                            return moduleUnitOfWork.get( resultType, foundEntity.identity() );
-                        }
-                        catch( NoSuchEntityException e )
-                        {
-                            // Index is out of sync - entity has been removed
-                            return null;
-                        }
-                    }
-
-                    @Override
-                    public void remove()
-                    {
-                        throw new UnsupportedOperationException();
-                    }
-                };
-            }
-            catch( EntityFinderException e )
-            {
-                throw new QueryExecutionException( "Query '" + toString() + "' could not be executed", e );
-            }
-        }
-
-        @Override
-        public String toString()
-        {
-            return "UnitOfWork( " + moduleUnitOfWork.usecase().name() + " )";
-        }
-    }
-
-    private class ToValuePropertyMappingFunction
-        implements Function<PropertyDescriptor, Object>
-    {
-        private Object entity;
-
-        public ToValuePropertyMappingFunction( Object entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public Object apply( PropertyDescriptor propertyDescriptor )
-        {
-            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
-            return entityState.propertyValueOf( propertyDescriptor.qualifiedName() );
-        }
-    }
-
-    private class ToValueAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, EntityReference>
-    {
-        private final T entity;
-
-        public ToValueAssociationMappingFunction( T entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public EntityReference apply( AssociationDescriptor associationDescriptor )
-        {
-            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
-            return entityState.associationValueOf( associationDescriptor.qualifiedName() );
-        }
-    }
-
-    private class ToValueManyAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
-    {
-        private final T entity;
-
-        public ToValueManyAssociationMappingFunction( T entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public Iterable<EntityReference> apply( AssociationDescriptor associationDescriptor )
-        {
-            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
-            return entityState.manyAssociationValueOf( associationDescriptor.qualifiedName() );
-        }
-    }
-
-    private class ToValueNameAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
-    {
-        private final T entity;
-
-        public ToValueNameAssociationMappingFunction( T entity )
-        {
-            this.entity = entity;
-        }
-
-        @Override
-        public Map<String, EntityReference> apply( AssociationDescriptor associationDescriptor )
-        {
-            Map<String, EntityReference> result = new HashMap<>();
-            EntityState entityState = EntityInstance.entityInstanceOf( (EntityComposite) entity ).entityState();
-            final NamedAssociationState state = entityState.namedAssociationValueOf( associationDescriptor.qualifiedName() );
-            for( String name : state )
-            {
-                result.put( name, state.get( name ) );
-            }
-            return result;
-        }
-    }
-
-    private class ToEntityPropertyMappingFunction<T>
-        implements Function<PropertyDescriptor, Object>
-    {
-        private final T value;
-
-        public ToEntityPropertyMappingFunction( T value )
-        {
-            this.value = value;
-        }
-
-        @Override
-        public Object apply( PropertyDescriptor propertyDescriptor )
-        {
-            StateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
-            Property<Object> property = state.propertyFor( propertyDescriptor.accessor() );
-            return property.get();
-        }
-    }
-
-    private class ToEntityAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, EntityReference>
-    {
-
-        private final T value;
-
-        public ToEntityAssociationMappingFunction( T value )
-        {
-            this.value = value;
-        }
-
-        @Override
-        public EntityReference apply( AssociationDescriptor associationDescriptor )
-        {
-            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
-            AssociationInstance<T> association = (AssociationInstance<T>) state.associationFor( associationDescriptor.accessor() );
-            return association.getAssociationState().get();
-        }
-    }
-
-    private class ToEntityManyAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Iterable<EntityReference>>
-    {
-
-        private final T value;
-
-        public ToEntityManyAssociationMappingFunction( T valueComposite )
-        {
-            this.value = valueComposite;
-        }
-
-        @Override
-        public Iterable<EntityReference> apply( AssociationDescriptor associationDescriptor )
-        {
-            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
-            ManyAssociationInstance<T> association =
-                (ManyAssociationInstance<T>) state.manyAssociationFor( associationDescriptor.accessor() );
-            return association.getManyAssociationState();
-        }
-    }
-
-    private class ToEntityNameAssociationMappingFunction<T>
-        implements Function<AssociationDescriptor, Map<String, EntityReference>>
-    {
-        private final T value;
-
-        public ToEntityNameAssociationMappingFunction( T valueComposite )
-        {
-            this.value = valueComposite;
-        }
-
-        @Override
-        public Map<String, EntityReference> apply( AssociationDescriptor associationDescriptor )
-        {
-            AssociationStateHolder state = ValueInstance.valueInstanceOf( (ValueComposite) value ).state();
-            NamedAssociationInstance<T> association =
-                (NamedAssociationInstance<T>) state.namedAssociationFor( associationDescriptor.accessor() );
-            HashMap<String, EntityReference> result = new HashMap<>();
-            for( Map.Entry<String, EntityReference> entry : association.getEntityReferences() )
-            {
-                result.put( entry.getKey(), entry.getValue() );
-            }
-            return result;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java
deleted file mode 100755
index 6947b73..0000000
--- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright (c) 2008-2012, Rickard Öberg.
- * Copyright (c) 2008-2012, Niclas Hedhman.
- * Copyright (c) 2012, Paul Merlin.
- *
- * 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.apache.zest.runtime.structure;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.zest.api.common.Visibility;
-import org.apache.zest.api.composite.AmbiguousTypeException;
-import org.apache.zest.api.composite.ModelDescriptor;
-import org.apache.zest.api.composite.TransientDescriptor;
-import org.apache.zest.api.entity.EntityDescriptor;
-import org.apache.zest.api.object.ObjectDescriptor;
-import org.apache.zest.api.service.NoSuchServiceException;
-import org.apache.zest.api.service.ServiceReference;
-import org.apache.zest.api.type.HasTypes;
-import org.apache.zest.api.value.ValueDescriptor;
-import org.apache.zest.spi.module.ModelModule;
-
-import static java.util.stream.Stream.concat;
-import static org.apache.zest.api.common.Visibility.application;
-import static org.apache.zest.api.common.Visibility.layer;
-import static org.apache.zest.api.common.Visibility.module;
-import static org.apache.zest.api.util.Classes.RAW_CLASS;
-import static org.apache.zest.api.util.Classes.interfacesOf;
-import static org.apache.zest.functional.Iterables.first;
-
-/**
- * Central place for Composite Type lookups.
- */
-public class TypeLookup
-{
-
-    // Constructor parameters
-    private final ModuleInstance moduleInstance;
-    // Eager instance objects
-    private final Map<Class<?>, ModelModule<ObjectDescriptor>> objectModels;
-    private final Map<Class<?>, ModelModule<TransientDescriptor>> transientModels;
-    private final Map<Class<?>, ModelModule<ValueDescriptor>> valueModels;
-    private final Map<Class<?>, List<ModelModule<EntityDescriptor>>> allEntityModels;
-    private final Map<Class<?>, ModelModule<EntityDescriptor>> unambiguousEntityModels;
-    private final Map<Type, ServiceReference<?>> serviceReferences;
-    private final Map<Type, List<ServiceReference<?>>> servicesReferences;
-
-    /**
-     * Create a new TypeLookup bound to the given ModuleInstance.
-     *
-     * @param moduleInstance ModuleInstance bound to this TypeLookup
-     */
-    TypeLookup( ModuleInstance moduleInstance )
-    {
-        // Constructor parameters
-        this.moduleInstance = moduleInstance;
-
-        // Eager instance objects
-        objectModels = new ConcurrentHashMap<>();
-        transientModels = new ConcurrentHashMap<>();
-        valueModels = new ConcurrentHashMap<>();
-        allEntityModels = new ConcurrentHashMap<>();
-        unambiguousEntityModels = new ConcurrentHashMap<>();
-        serviceReferences = new ConcurrentHashMap<>();
-        servicesReferences = new ConcurrentHashMap<>();
-    }
-
-    /**
-     * Lookup first Object Model matching the given Type.
-     *
-     * <p>First, if Object Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Second, if Object Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * @param type Looked up Type
-     *
-     * @return First matching Object Model
-     */
-    ModelModule<ObjectDescriptor> lookupObjectModel( final Class type )
-    {
-        ModelModule<ObjectDescriptor> model = objectModels.get( type );
-        if( model == null )
-        {
-            List<ModelModule<ObjectDescriptor>> allModels = allObjects().collect( Collectors.toList() );
-            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
-            if( model == null )
-            {
-                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
-            }
-            if( model != null )
-            {
-                objectModels.put( type, model );
-            }
-        }
-        return model;
-    }
-
-    /**
-     * Lookup first Transient Model matching the given Type.
-     *
-     * <p>First, if Transient Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Second, if Transient Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * @param type Looked up Type
-     *
-     * @return First matching Transient Model
-     */
-    ModelModule<TransientDescriptor> lookupTransientModel( final Class type )
-    {
-        ModelModule<TransientDescriptor> model = transientModels.get( type );
-        if( model == null )
-        {
-            List<ModelModule<TransientDescriptor>> allModels = allTransients().collect( Collectors.toList() );
-            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
-            if( model == null )
-            {
-                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
-            }
-            if( model != null )
-            {
-                transientModels.put( type, model );
-            }
-        }
-        return model;
-    }
-
-    /**
-     * Lookup first Value Model matching the given Type.
-     *
-     * <p>First, if Value Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Second, if Value Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * @param type Looked up Type
-     *
-     * @return First matching Value Model
-     */
-    public ModelModule<ValueDescriptor> lookupValueModel( final Class type )
-    {
-        ModelModule<ValueDescriptor> model = valueModels.get( type );
-        if( model == null )
-        {
-            List<ModelModule<ValueDescriptor>> allModels = allValues().collect( Collectors.toList() );
-            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
-            if( model == null )
-            {
-                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
-            }
-            if( model != null )
-            {
-                valueModels.put( type, model );
-            }
-        }
-        return model;
-    }
-
-    /**
-     * Lookup first Entity Model matching the given Type.
-     *
-     * <p>First, if Entity Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Second, if Entity Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
-     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * <p><b>Should be used for creational use cases only.</b> For non-creational use cases see
-     * {@link #lookupEntityModels(java.lang.Class)}.</p>
-     *
-     * @param type Looked up Type
-     *
-     * @return First matching Entity Model
-     */
-    ModelModule<EntityDescriptor> lookupEntityModel( final Class type )
-    {
-        ModelModule<EntityDescriptor> model = unambiguousEntityModels.get( type );
-
-        if( model == null )
-        {
-            List<ModelModule<EntityDescriptor>> allModels = allEntities().collect( Collectors.toList() );
-            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
-            if( model == null )
-            {
-                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
-            }
-            if( model != null )
-            {
-                unambiguousEntityModels.put( type, model );
-            }
-        }
-        return model;
-    }
-
-    /**
-     * Lookup all Entity Models matching the given Type.
-     *
-     * <p>Returned Iterable contains, in order, Entity Models that: </p>
-     *
-     * <ul>
-     * <li>exactly match the given type, in Visibility then Assembly order ;</li>
-     * <li>match a type assignable to the given type, in Visibility then Assembly order.</li>
-     * </ul>
-     *
-     * <p>Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
-     * <p>Multiple <b>assignable</b> matches are <b>allowed</b> to enable polymorphic fetches and queries.</p>
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * <p><b>Should be used for non-creational use cases only.</b> For creational use cases see
-     * {@link #lookupEntityModel(java.lang.Class)}.</p>
-     *
-     * @param type Looked up Type
-     *
-     * @return All matching Entity Models
-     */
-    Iterable<ModelModule<EntityDescriptor>> lookupEntityModels( final Class type )
-    {
-        List<ModelModule<EntityDescriptor>> result = allEntityModels.get( type );
-        if( result == null )
-        {
-            result = concat(
-                allEntities().filter( ref -> new ExactTypeMatching<>( type ).test( ref.model() ) ),
-                allEntities().filter( ref -> new AssignableFromTypeMatching<>( type ).test( ref.model() ) )
-            ).distinct().collect( Collectors.toList() );
-            allEntityModels.put( type, result );
-        }
-        return result;
-    }
-
-    /**
-     * Lookup first ServiceReference matching the given Type.
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * <p>See {@link #lookupServiceReferences(Type)}.</p>
-     *
-     * @param <T>         Service Type
-     * @param serviceType Looked up Type
-     *
-     * @return First matching ServiceReference
-     */
-    <T> ServiceReference<T> lookupServiceReference( Type serviceType )
-    {
-        @SuppressWarnings( "unchecked" )
-        ServiceReference<T> serviceReference = (ServiceReference<T>) serviceReferences.get( serviceType );
-        if( serviceReference == null )
-        {
-            // Lazily resolve ServiceReference
-            serviceReference = first( lookupServiceReferences( serviceType ) );
-            if( serviceReference != null )
-            {
-                serviceReferences.put( serviceType, serviceReference );
-            }
-        }
-
-        if( serviceReference == null )
-        {
-            throw new NoSuchServiceException( RAW_CLASS.apply( serviceType ).getName(), moduleInstance.name() );
-        }
-        return serviceReference;
-    }
-
-    /**
-     * Lookup all ServiceReferences matching the given Type.
-     *
-     * <p>Returned Iterable contains, in order, ServiceReferences that: </p>
-     *
-     * <ul>
-     * <li>exactly match the given type, in Visibility then Assembly order ;</li>
-     * <li>match a type assignable to the given type, in Visibility then Assembly order.</li>
-     * </ul>
-     *
-     * <p>Multiple <b>exact</b> matches with the same Visibility are <b>allowed</b> to enable polymorphic lookup/injection.</p>
-     * <p>Multiple <b>assignable</b> matches with the same Visibility are <b>allowed</b> for the very same reason.</p>
-     *
-     * <p>Type lookup is done lazily and cached.</p>
-     *
-     * @param <T>  Service Type
-     * @param type Looked up Type
-     *
-     * @return All matching ServiceReferences
-     */
-    <T> List<ServiceReference<T>> lookupServiceReferences( final Type type )
-    {
-        List<ServiceReference<?>> serviceRefs = servicesReferences.get( type );
-        if( serviceRefs == null )
-        {
-            serviceRefs = concat(
-                allServices()
-                    .filter( new ExactTypeMatching<>( type  ) ),
-                allServices()
-                    .filter( new AssignableFromTypeMatching<>( type )
-                    )
-            ).distinct().collect( Collectors.toList() );
-            servicesReferences.put( type, serviceRefs );
-        }
-        List<ServiceReference<T>> result = new ArrayList<>();
-        //noinspection unchecked
-        serviceRefs.forEach( ref -> result.add( (ServiceReference<T>) ref ) );
-        return result;
-    }
-
-    public Stream<Class<?>> allVisibleObjects()
-    {
-        return allObjects().flatMap( model -> model.model().types() );
-    }
-
-    private Stream<ModelModule<ObjectDescriptor>> allObjects()
-    {
-        return concat( moduleInstance.visibleObjects( module ),
-                       concat(
-                           moduleInstance.layerInstance().visibleObjects( layer ),
-                           concat(
-                               moduleInstance.layerInstance().visibleObjects( application ),
-                               moduleInstance.layerInstance().usedLayersInstance().visibleObjects()
-                           )
-                       )
-        );
-    }
-
-    private Stream<ModelModule<TransientDescriptor>> allTransients()
-    {
-        return concat( moduleInstance.visibleTransients( module ),
-                       concat(
-                           moduleInstance.layerInstance().visibleTransients( layer ),
-                           concat(
-                               moduleInstance.layerInstance().visibleTransients( application ),
-                               moduleInstance.layerInstance().usedLayersInstance().visibleTransients()
-                           )
-                       )
-        );
-    }
-
-    private Stream<ModelModule<ValueDescriptor>> allValues()
-    {
-        return concat( moduleInstance.visibleValues( module ),
-                       concat(
-                           moduleInstance.layerInstance().visibleValues( layer ),
-                           concat(
-                               moduleInstance.layerInstance().visibleValues( application ),
-                               moduleInstance.layerInstance().usedLayersInstance().visibleValues()
-                           )
-                       )
-        );
-    }
-
-    private Stream<ModelModule<EntityDescriptor>> allEntities()
-    {
-        return concat( moduleInstance.visibleEntities( module ),
-                       concat(
-                           moduleInstance.layerInstance().visibleEntities( layer ),
-                           concat(
-                               moduleInstance.layerInstance().visibleEntities( application ),
-                               moduleInstance.layerInstance().usedLayersInstance().visibleEntities()
-                           )
-                       )
-        );
-    }
-
-    private Stream<ServiceReference<?>> allServices()
-    {
-        return concat( moduleInstance.visibleServices( module ),
-                       concat(
-                           moduleInstance.layerInstance().visibleServices( layer ),
-                           concat(
-                               moduleInstance.layerInstance().visibleServices( application ),
-                               moduleInstance.layerInstance().usedLayersInstance().visibleServices()
-                           )
-                       )
-        );
-    }
-
-    private <T extends ModelDescriptor> ModelModule<T> ambiguityMatching(
-        Class type,
-        List<ModelModule<T>> modelModules,
-        TypeMatching<T> matching
-    )
-    {
-        List<ModelModule<T>> models = modelModules.stream()
-            .filter( ref -> matching.test( ref.model() ) )
-            .filter( new SameVisibility<>() )
-            .distinct()
-            .collect( Collectors.toList() );
-
-        if( models.size() > 1 )
-        {
-            throw new AmbiguousTypeException( "More than one type matches " + type.getName() + ": " + models + "]" );
-        }
-        if( models.isEmpty() )
-        {
-            return null;
-        }
-        return models.get( 0 );
-    }
-
-    private static abstract class TypeMatching<T extends HasTypes>
-        implements Predicate<T>
-    {
-        protected final Type lookedUpType;
-
-        protected TypeMatching( Type lookedUpType )
-        {
-            this.lookedUpType = lookedUpType;
-        }
-
-        @Override
-        public final boolean test( T model )
-        {
-            if( lookedUpType instanceof Class )
-            {
-                return model.types().anyMatch( checkMatch( lookedUpType ) );
-            }
-            else
-            {
-                if( lookedUpType instanceof ParameterizedType )
-                {
-                    // Foo<Bar> check
-                    // First check Foo
-                    ParameterizedType parameterizedType = (ParameterizedType) lookedUpType;
-                    Type rawType = parameterizedType.getRawType();
-                    if( !model.types().anyMatch( checkMatch( rawType ) ) )
-                    {
-                        return false;
-                    }
-                    // Then check Bar
-                    return interfacesOf( model.types() ).anyMatch( intf -> intf.equals( lookedUpType ) );
-                }
-                else if( lookedUpType instanceof WildcardType )
-                {
-                    return true;
-                }
-                return false;
-            }
-        }
-
-        protected abstract Predicate<Type> checkMatch( Type matchTo );
-    }
-
-    private static final class ExactTypeMatching<T extends HasTypes> extends TypeMatching<T>
-    {
-        private ExactTypeMatching( Type lookedUpType )
-        {
-            super( lookedUpType );
-        }
-
-        protected Predicate<Type> checkMatch( Type matchTo )
-        {
-            return matchTo::equals;
-        }
-    }
-
-    private static final class AssignableFromTypeMatching<T extends HasTypes> extends TypeMatching<T>
-    {
-        private AssignableFromTypeMatching( Type lookedUpType )
-        {
-            super( lookedUpType );
-        }
-
-        protected Predicate<Type> checkMatch( Type matchTo )
-        {
-            // TODO; what to do if there is ParameterizedType here?? Now set to ClassCastException and see if anything surfaces
-//            if( matchTo instanceof Class )
-            {
-                Class<?> clazz = (Class<?>) matchTo;
-                return candidate ->
-                    !candidate.equals( matchTo ) && clazz.isAssignableFrom( (Class<?>) candidate );
-            }
-//            return candidate -> candidate.equals( matchTo );
-        }
-    }
-
-    /**
-     * This Predicate will filter out all Models that doesn't have the same visisbility as the first one.
-     */
-    private class SameVisibility<T extends ModelDescriptor>
-        implements Predicate<ModelModule<T>>
-    {
-        private Visibility current = null;
-
-        @Override
-        public boolean test( ModelModule<T> model )
-        {
-            if( current == null )
-            {
-                current = model.model().visibility();
-                return true;
-            }
-            return current == model.model().visibility();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java
new file mode 100755
index 0000000..7835aaa
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2008-2012, Rickard Öberg.
+ * Copyright (c) 2008-2012, Niclas Hedhman.
+ * Copyright (c) 2012, Paul Merlin.
+ *
+ * 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.apache.zest.runtime.structure;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.zest.api.common.Visibility;
+import org.apache.zest.api.composite.AmbiguousTypeException;
+import org.apache.zest.api.composite.ModelDescriptor;
+import org.apache.zest.api.composite.TransientDescriptor;
+import org.apache.zest.api.entity.EntityDescriptor;
+import org.apache.zest.api.object.ObjectDescriptor;
+import org.apache.zest.api.service.NoSuchServiceException;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.api.type.HasTypes;
+import org.apache.zest.api.value.ValueDescriptor;
+import org.apache.zest.spi.structure.ModelModule;
+import org.apache.zest.spi.structure.TypeLookup;
+
+import static java.util.stream.Stream.concat;
+import static org.apache.zest.api.common.Visibility.application;
+import static org.apache.zest.api.common.Visibility.layer;
+import static org.apache.zest.api.common.Visibility.module;
+import static org.apache.zest.api.util.Classes.RAW_CLASS;
+import static org.apache.zest.api.util.Classes.interfacesOf;
+import static org.apache.zest.functional.Iterables.first;
+
+/**
+ * Central place for Composite Type lookups.
+ */
+public class TypeLookupImpl
+    implements TypeLookup
+{
+
+    // Constructor parameters
+    private final ModuleInstance moduleInstance;
+    // Eager instance objects
+    private final Map<Class<?>, ModelModule<ObjectDescriptor>> objectModels;
+    private final Map<Class<?>, ModelModule<TransientDescriptor>> transientModels;
+    private final Map<Class<?>, ModelModule<ValueDescriptor>> valueModels;
+    private final Map<Class<?>, List<ModelModule<EntityDescriptor>>> allEntityModels;
+    private final Map<Class<?>, ModelModule<EntityDescriptor>> unambiguousEntityModels;
+    private final Map<Type, ServiceReference<?>> serviceReferences;
+    private final Map<Type, List<ServiceReference<?>>> servicesReferences;
+
+    /**
+     * Create a new TypeLookup bound to the given ModuleInstance.
+     *
+     * @param moduleInstance ModuleInstance bound to this TypeLookup
+     */
+    TypeLookupImpl( ModuleInstance moduleInstance )
+    {
+        // Constructor parameters
+        this.moduleInstance = moduleInstance;
+
+        // Eager instance objects
+        objectModels = new ConcurrentHashMap<>();
+        transientModels = new ConcurrentHashMap<>();
+        valueModels = new ConcurrentHashMap<>();
+        allEntityModels = new ConcurrentHashMap<>();
+        unambiguousEntityModels = new ConcurrentHashMap<>();
+        serviceReferences = new ConcurrentHashMap<>();
+        servicesReferences = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * Lookup first Object Model matching the given Type.
+     *
+     * <p>First, if Object Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Second, if Object Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * @param type Looked up Type
+     *
+     * @return First matching Object Model
+     */
+    ModelModule<ObjectDescriptor> lookupObjectModel( final Class type )
+    {
+        ModelModule<ObjectDescriptor> model = objectModels.get( type );
+        if( model == null )
+        {
+            List<ModelModule<ObjectDescriptor>> allModels = allObjects().collect( Collectors.toList() );
+            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
+            if( model == null )
+            {
+                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
+            }
+            if( model != null )
+            {
+                objectModels.put( type, model );
+            }
+        }
+        return model;
+    }
+
+    /**
+     * Lookup first Transient Model matching the given Type.
+     *
+     * <p>First, if Transient Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Second, if Transient Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * @param type Looked up Type
+     *
+     * @return First matching Transient Model
+     */
+    ModelModule<TransientDescriptor> lookupTransientModel( final Class type )
+    {
+        ModelModule<TransientDescriptor> model = transientModels.get( type );
+        if( model == null )
+        {
+            List<ModelModule<TransientDescriptor>> allModels = allTransients().collect( Collectors.toList() );
+            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
+            if( model == null )
+            {
+                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
+            }
+            if( model != null )
+            {
+                transientModels.put( type, model );
+            }
+        }
+        return model;
+    }
+
+    /**
+     * Lookup first Value Model matching the given Type.
+     *
+     * <p>First, if Value Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Second, if Value Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * @param type Looked up Type
+     *
+     * @return First matching Value Model
+     */
+    public ModelModule<ValueDescriptor> lookupValueModel( final Class type )
+    {
+        ModelModule<ValueDescriptor> model = valueModels.get( type );
+        if( model == null )
+        {
+            List<ModelModule<ValueDescriptor>> allModels = allValues().collect( Collectors.toList() );
+            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
+            if( model == null )
+            {
+                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
+            }
+            if( model != null )
+            {
+                valueModels.put( type, model );
+            }
+        }
+        return model;
+    }
+
+    /**
+     * Lookup first Entity Model matching the given Type.
+     *
+     * <p>First, if Entity Models exactly match the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Second, if Entity Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned.
+     * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * <p><b>Should be used for creational use cases only.</b> For non-creational use cases see
+     * {@link #lookupEntityModels(java.lang.Class)}.</p>
+     *
+     * @param type Looked up Type
+     *
+     * @return First matching Entity Model
+     */
+    @Override
+    public ModelModule<EntityDescriptor> lookupEntityModel( final Class type )
+    {
+        ModelModule<EntityDescriptor> model = unambiguousEntityModels.get( type );
+
+        if( model == null )
+        {
+            List<ModelModule<EntityDescriptor>> allModels = allEntities().collect( Collectors.toList() );
+            model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) );
+            if( model == null )
+            {
+                model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) );
+            }
+            if( model != null )
+            {
+                unambiguousEntityModels.put( type, model );
+            }
+        }
+        return model;
+    }
+
+    /**
+     * Lookup all Entity Models matching the given Type.
+     *
+     * <p>Returned Iterable contains, in order, Entity Models that: </p>
+     *
+     * <ul>
+     * <li>exactly match the given type, in Visibility then Assembly order ;</li>
+     * <li>match a type assignable to the given type, in Visibility then Assembly order.</li>
+     * </ul>
+     *
+     * <p>Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p>
+     * <p>Multiple <b>assignable</b> matches are <b>allowed</b> to enable polymorphic fetches and queries.</p>
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * <p><b>Should be used for non-creational use cases only.</b> For creational use cases see
+     * {@link #lookupEntityModel(java.lang.Class)}.</p>
+     *
+     * @param type Looked up Type
+     *
+     * @return All matching Entity Models
+     */
+    @Override
+    public Iterable<ModelModule<EntityDescriptor>> lookupEntityModels( final Class type )
+    {
+        List<ModelModule<EntityDescriptor>> result = allEntityModels.get( type );
+        if( result == null )
+        {
+            result = concat(
+                allEntities().filter( ref -> new ExactTypeMatching<>( type ).test( ref.model() ) ),
+                allEntities().filter( ref -> new AssignableFromTypeMatching<>( type ).test( ref.model() ) )
+            ).distinct().collect( Collectors.toList() );
+            allEntityModels.put( type, result );
+        }
+        return result;
+    }
+
+    /**
+     * Lookup first ServiceReference matching the given Type.
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * <p>See {@link #lookupServiceReferences(Type)}.</p>
+     *
+     * @param <T>         Service Type
+     * @param serviceType Looked up Type
+     *
+     * @return First matching ServiceReference
+     */
+    @Override
+    public <T> ServiceReference<T> lookupServiceReference( Type serviceType )
+    {
+        @SuppressWarnings( "unchecked" )
+        ServiceReference<T> serviceReference = (ServiceReference<T>) serviceReferences.get( serviceType );
+        if( serviceReference == null )
+        {
+            // Lazily resolve ServiceReference
+            serviceReference = first( lookupServiceReferences( serviceType ) );
+            if( serviceReference != null )
+            {
+                serviceReferences.put( serviceType, serviceReference );
+            }
+        }
+
+        if( serviceReference == null )
+        {
+            throw new NoSuchServiceException( RAW_CLASS.apply( serviceType ).getName(), moduleInstance.name() );
+        }
+        return serviceReference;
+    }
+
+    /**
+     * Lookup all ServiceReferences matching the given Type.
+     *
+     * <p>Returned Iterable contains, in order, ServiceReferences that: </p>
+     *
+     * <ul>
+     * <li>exactly match the given type, in Visibility then Assembly order ;</li>
+     * <li>match a type assignable to the given type, in Visibility then Assembly order.</li>
+     * </ul>
+     *
+     * <p>Multiple <b>exact</b> matches with the same Visibility are <b>allowed</b> to enable polymorphic lookup/injection.</p>
+     * <p>Multiple <b>assignable</b> matches with the same Visibility are <b>allowed</b> for the very same reason.</p>
+     *
+     * <p>Type lookup is done lazily and cached.</p>
+     *
+     * @param <T>  Service Type
+     * @param type Looked up Type
+     *
+     * @return All matching ServiceReferences
+     */
+    @Override
+    public <T> List<ServiceReference<T>> lookupServiceReferences( final Type type )
+    {
+        List<ServiceReference<?>> serviceRefs = servicesReferences.get( type );
+        if( serviceRefs == null )
+        {
+            serviceRefs = concat(
+                allServices()
+                    .filter( new ExactTypeMatching<>( type  ) ),
+                allServices()
+                    .filter( new AssignableFromTypeMatching<>( type )
+                    )
+            ).distinct().collect( Collectors.toList() );
+            servicesReferences.put( type, serviceRefs );
+        }
+        List<ServiceReference<T>> result = new ArrayList<>();
+        //noinspection unchecked
+        serviceRefs.forEach( ref -> result.add( (ServiceReference<T>) ref ) );
+        return result;
+    }
+
+    @Override
+    public Stream<Class<?>> allVisibleObjects()
+    {
+        return allObjects().flatMap( model -> model.model().types() );
+    }
+
+    @Override
+    public Stream<ModelModule<ObjectDescriptor>> allObjects()
+    {
+        return concat( moduleInstance.visibleObjects( module ),
+                       concat(
+                           moduleInstance.layerInstance().visibleObjects( layer ),
+                           concat(
+                               moduleInstance.layerInstance().visibleObjects( application ),
+                               moduleInstance.layerInstance().usedLayersInstance().visibleObjects()
+                           )
+                       )
+        );
+    }
+
+    @Override
+    public Stream<ModelModule<TransientDescriptor>> allTransients()
+    {
+        return concat( moduleInstance.visibleTransients( module ),
+                       concat(
+                           moduleInstance.layerInstance().visibleTransients( layer ),
+                           concat(
+                               moduleInstance.layerInstance().visibleTransients( application ),
+                               moduleInstance.layerInstance().usedLayersInstance().visibleTransients()
+                           )
+                       )
+        );
+    }
+
+    @Override
+    public Stream<ModelModule<ValueDescriptor>> allValues()
+    {
+        return concat( moduleInstance.visibleValues( module ),
+                       concat(
+                           moduleInstance.layerInstance().visibleValues( layer ),
+                           concat(
+                               moduleInstance.layerInstance().visibleValues( application ),
+                               moduleInstance.layerInstance().usedLayersInstance().visibleValues()
+                           )
+                       )
+        );
+    }
+
+    @Override
+    public Stream<ModelModule<EntityDescriptor>> allEntities()
+    {
+        return concat( moduleInstance.visibleEntities( module ),
+                       concat(
+                           moduleInstance.layerInstance().visibleEntities( layer ),
+                           concat(
+                               moduleInstance.layerInstance().visibleEntities( application ),
+                               moduleInstance.layerInstance().usedLayersInstance().visibleEntities()
+                           )
+                       )
+        );
+    }
+
+    @Override
+    public Stream<ServiceReference<?>> allServices()
+    {
+        return concat( moduleInstance.visibleServices( module ),
+                       concat(
+                           moduleInstance.layerInstance().visibleServices( layer ),
+                           concat(
+                               moduleInstance.layerInstance().visibleServices( application ),
+                               moduleInstance.layerInstance().usedLayersInstance().visibleServices()
+                           )
+                       )
+        );
+    }
+
+    private <T extends ModelDescriptor> ModelModule<T> ambiguityMatching(
+        Class type,
+        List<ModelModule<T>> modelModules,
+        TypeMatching<T> matching
+    )
+    {
+        List<ModelModule<T>> models = modelModules.stream()
+            .filter( ref -> matching.test( ref.model() ) )
+            .filter( new SameVisibility<>() )
+            .distinct()
+            .collect( Collectors.toList() );
+
+        if( models.size() > 1 )
+        {
+            throw new AmbiguousTypeException( "More than one type matches " + type.getName() + ": " + models + "]" );
+        }
+        if( models.isEmpty() )
+        {
+            return null;
+        }
+        return models.get( 0 );
+    }
+
+    private static abstract class TypeMatching<T extends HasTypes>
+        implements Predicate<T>
+    {
+        protected final Type lookedUpType;
+
+        protected TypeMatching( Type lookedUpType )
+        {
+            this.lookedUpType = lookedUpType;
+        }
+
+        @Override
+        public final boolean test( T model )
+        {
+            if( lookedUpType instanceof Class )
+            {
+                return model.types().anyMatch( checkMatch( lookedUpType ) );
+            }
+            else
+            {
+                if( lookedUpType instanceof ParameterizedType )
+                {
+                    // Foo<Bar> check
+                    // First check Foo
+                    ParameterizedType parameterizedType = (ParameterizedType) lookedUpType;
+                    Type rawType = parameterizedType.getRawType();
+                    if( !model.types().anyMatch( checkMatch( rawType ) ) )
+                    {
+                        return false;
+                    }
+                    // Then check Bar
+                    return interfacesOf( model.types() ).anyMatch( intf -> intf.equals( lookedUpType ) );
+                }
+                else if( lookedUpType instanceof WildcardType )
+                {
+                    return true;
+                }
+                return false;
+            }
+        }
+
+        protected abstract Predicate<Type> checkMatch( Type matchTo );
+    }
+
+    private static final class ExactTypeMatching<T extends HasTypes> extends TypeMatching<T>
+    {
+        private ExactTypeMatching( Type lookedUpType )
+        {
+            super( lookedUpType );
+        }
+
+        protected Predicate<Type> checkMatch( Type matchTo )
+        {
+            return matchTo::equals;
+        }
+    }
+
+    private static final class AssignableFromTypeMatching<T extends HasTypes> extends TypeMatching<T>
+    {
+        private AssignableFromTypeMatching( Type lookedUpType )
+        {
+            super( lookedUpType );
+        }
+
+        protected Predicate<Type> checkMatch( Type matchTo )
+        {
+            // TODO; what to do if there is ParameterizedType here?? Now set to ClassCastException and see if anything surfaces
+//            if( matchTo instanceof Class )
+            {
+                Class<?> clazz = (Class<?>) matchTo;
+                return candidate ->
+                    !candidate.equals( matchTo ) && clazz.isAssignableFrom( (Class<?>) candidate );
+            }
+//            return candidate -> candidate.equals( matchTo );
+        }
+    }
+
+    /**
+     * This Predicate will filter out all Models that doesn't have the same visisbility as the first one.
+     */
+    private class SameVisibility<T extends ModelDescriptor>
+        implements Predicate<ModelModule<T>>
+    {
+        private Visibility current = null;
+
+        @Override
+        public boolean test( ModelModule<T> model )
+        {
+            if( current == null )
+            {
+                current = model.model().visibility();
+                return true;
+            }
+            return current == model.model().visibility();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java
index 5a9bc94..ebf4b9c 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java
@@ -17,13 +17,12 @@ package org.apache.zest.runtime.structure;
 import java.util.List;
 import java.util.stream.Stream;
 import org.apache.zest.api.common.Visibility;
-import org.apache.zest.api.composite.ModelDescriptor;
 import org.apache.zest.api.composite.TransientDescriptor;
 import org.apache.zest.api.entity.EntityDescriptor;
 import org.apache.zest.api.object.ObjectDescriptor;
 import org.apache.zest.api.service.ServiceReference;
 import org.apache.zest.api.value.ValueDescriptor;
-import org.apache.zest.spi.module.ModelModule;
+import org.apache.zest.spi.structure.ModelModule;
 
 /**
  * JAVADOC

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java
index 425e851..ed8d137 100755
--- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java
@@ -25,8 +25,7 @@ import org.apache.zest.api.entity.LifecycleException;
 import org.apache.zest.runtime.composite.FunctionStateResolver;
 import org.apache.zest.runtime.entity.EntityInstance;
 import org.apache.zest.runtime.entity.EntityModel;
-import org.apache.zest.spi.module.ModelModule;
-import org.apache.zest.runtime.structure.ModuleUnitOfWork;
+import org.apache.zest.spi.structure.ModelModule;
 import org.apache.zest.spi.entity.EntityState;
 import org.apache.zest.spi.entitystore.EntityStoreUnitOfWork;
 import org.apache.zest.spi.module.ModuleSpi;

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a5be013f/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityFunction.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityFunction.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityFunction.java
new file mode 100644
index 0000000..a7524db
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityFunction.java
@@ -0,0 +1,46 @@
+/*
+ * 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.unitofwork;
+
+import java.lang.reflect.Type;
+import java.util.function.BiFunction;
+import org.apache.zest.api.entity.EntityReference;
+import org.apache.zest.api.unitofwork.UnitOfWorkFactory;
+
+import static org.apache.zest.api.util.Classes.RAW_CLASS;
+
+public class EntityFunction
+    implements BiFunction<EntityReference, Type, Object>
+{
+
+    private final UnitOfWorkFactory uowf;
+
+    public EntityFunction( UnitOfWorkFactory uowf )
+    {
+        this.uowf = uowf;
+    }
+
+    @Override
+    public Object apply( EntityReference entityReference, Type type )
+    {
+        return uowf.currentUnitOfWork().get( RAW_CLASS.apply( type ), entityReference.identity() );
+    }
+}


Mime
View raw message