/*
 * Copyright (c) 2008-2012, Rickard Öberg. All Rights Reserved.
 * Copyright (c) 2012, Kent Sølvsten. All Rights Reserved.
 * Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved.
 * Copyright (c) 2012-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.qi4j.runtime.structure;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Type;
import java.util.ArrayList;
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 org.qi4j.api.activation.Activation;
import org.qi4j.api.activation.ActivationEventListener;
import org.qi4j.api.activation.ActivationException;
import org.qi4j.api.activation.PassivationException;
import org.qi4j.api.association.AssociationDescriptor;
import org.qi4j.api.common.ConstructionException;
import org.qi4j.api.common.Visibility;
import org.qi4j.api.composite.AmbiguousTypeException;
import org.qi4j.api.composite.Composite;
import org.qi4j.api.composite.ModelDescriptor;
import org.qi4j.api.composite.NoSuchTransientException;
import org.qi4j.api.composite.TransientBuilder;
import org.qi4j.api.composite.TransientDescriptor;
import org.qi4j.api.entity.EntityComposite;
import org.qi4j.api.entity.EntityDescriptor;
import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.entity.IdentityGenerator;
import org.qi4j.api.metrics.MetricsProvider;
import org.qi4j.api.object.NoSuchObjectException;
import org.qi4j.api.object.ObjectDescriptor;
import org.qi4j.api.property.Property;
import org.qi4j.api.property.PropertyDescriptor;
import org.qi4j.api.query.QueryBuilder;
import org.qi4j.api.query.QueryBuilderFactory;
import org.qi4j.api.service.NoSuchServiceException;
import org.qi4j.api.service.ServiceDescriptor;
import org.qi4j.api.service.ServiceReference;
import org.qi4j.api.structure.Module;
import org.qi4j.api.unitofwork.UnitOfWork;
import org.qi4j.api.unitofwork.UnitOfWorkException;
import org.qi4j.api.unitofwork.UnitOfWorkFactory;
import org.qi4j.api.usecase.Usecase;
import org.qi4j.api.util.NullArgumentException;
import org.qi4j.api.value.NoSuchValueException;
import org.qi4j.api.value.ValueBuilder;
import org.qi4j.api.value.ValueComposite;
import org.qi4j.api.value.ValueDescriptor;
import org.qi4j.api.value.ValueSerialization;
import org.qi4j.api.value.ValueSerializationException;
import org.qi4j.functional.Function;
import org.qi4j.functional.Function2;
import org.qi4j.functional.Specification;
import org.qi4j.functional.Specifications;
import org.qi4j.runtime.activation.ActivationDelegate;
import org.qi4j.runtime.composite.FunctionStateResolver;
import org.qi4j.runtime.composite.StateResolver;
import org.qi4j.runtime.composite.TransientBuilderInstance;
import org.qi4j.runtime.composite.TransientModel;
import org.qi4j.runtime.composite.TransientStateInstance;
import org.qi4j.runtime.composite.TransientsModel;
import org.qi4j.runtime.composite.UsesInstance;
import org.qi4j.runtime.entity.EntitiesModel;
import org.qi4j.runtime.entity.EntityInstance;
import org.qi4j.runtime.entity.EntityModel;
import org.qi4j.runtime.injection.InjectionContext;
import org.qi4j.runtime.object.ObjectModel;
import org.qi4j.runtime.object.ObjectsModel;
import org.qi4j.runtime.property.PropertyInstance;
import org.qi4j.runtime.property.PropertyModel;
import org.qi4j.runtime.query.QueryBuilderFactoryImpl;
import org.qi4j.runtime.service.ImportedServicesInstance;
import org.qi4j.runtime.service.ImportedServicesModel;
import org.qi4j.runtime.service.ServicesInstance;
import org.qi4j.runtime.service.ServicesModel;
import org.qi4j.runtime.unitofwork.UnitOfWorkInstance;
import org.qi4j.runtime.value.ValueBuilderInstance;
import org.qi4j.runtime.value.ValueBuilderWithPrototype;
import org.qi4j.runtime.value.ValueBuilderWithState;
import org.qi4j.runtime.value.ValueInstance;
import org.qi4j.runtime.value.ValueModel;
import org.qi4j.runtime.value.ValuesModel;
import org.qi4j.spi.entitystore.EntityStore;
import org.qi4j.spi.metrics.MetricsProviderAdapter;
import org.qi4j.spi.module.ModelModule;
import org.qi4j.spi.module.ModuleSpi;
import org.qi4j.valueserialization.orgjson.OrgJsonValueSerialization;

import static org.qi4j.api.common.Visibility.application;
import static org.qi4j.api.common.Visibility.layer;
import static org.qi4j.api.common.Visibility.module;
import static org.qi4j.api.util.Classes.RAW_CLASS;
import static org.qi4j.api.util.Classes.modelTypeSpecification;
import static org.qi4j.functional.Iterables.cast;
import static org.qi4j.functional.Iterables.filter;
import static org.qi4j.functional.Iterables.first;
import static org.qi4j.functional.Iterables.flatten;
import static org.qi4j.functional.Iterables.iterable;
import static org.qi4j.functional.Iterables.map;
import static org.qi4j.functional.Iterables.toList;

/**
 * Instance of a Zest Module. Contains the various composites for this Module.
 */
public class ModuleInstance
    implements Module, ModuleSpi, Activation
{
    // Constructor parameters
    private final ModuleModel model;
    private final LayerInstance layer;
    private final TransientsModel transients;
    private final ValuesModel values;
    private final ObjectsModel objects;
    private final EntitiesModel entities;
    private final ServicesInstance services;
    private final ImportedServicesInstance importedServices;
    // Eager instance objects
    private final ActivationDelegate activation;
    private final TypeLookup 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;

    @SuppressWarnings( "LeakingThisInConstructor" )
    public ModuleInstance( ModuleModel moduleModel, LayerInstance layerInstance, TransientsModel transientsModel,
                           EntitiesModel entitiesModel, ObjectsModel objectsModel, ValuesModel valuesModel,
                           ServicesModel servicesModel, ImportedServicesModel importedServicesModel
    )
    {
        // Constructor parameters
        model = moduleModel;
        layer = layerInstance;
        transients = transientsModel;
        values = valuesModel;
        objects = objectsModel;
        entities = entitiesModel;
        services = servicesModel.newInstance( this );
        importedServices = importedServicesModel.newInstance( this );

        // Eager instance objects
        activation = new ActivationDelegate( this );
        typeLookup = new TypeLookup( this );
        queryBuilderFactory = new QueryBuilderFactoryImpl( this );
        classLoader = new ModuleClassLoader( this, Thread.currentThread().getContextClassLoader() );
        entityFunction = new EntityFunction( this );

        // Activation
        services.registerActivationEventListener( activation );
        importedServices.registerActivationEventListener( activation );
    }

    @Override
    public String toString()
    {
        return model.toString();
    }

    // Implementation of Module
    @Override
    public String name()
    {
        return model.name();
    }

    @Override
    public ClassLoader classLoader()
    {
        return classLoader;
    }

    @Override
    public EntityDescriptor entityDescriptor( String name )
    {
        try
        {
            Class<?> type = classLoader().loadClass( name );
            ModelModule<EntityModel> entityModel = typeLookup.lookupEntityModel( type );
            if( entityModel == null )
            {
                return null;
            }
            return entityModel.model();
        }
        catch( ClassNotFoundException e )
        {
            return null;
        }
    }

    @Override
    public ObjectDescriptor objectDescriptor( String typeName )
    {
        try
        {
            Class<?> type = classLoader().loadClass( typeName );
            ModelModule<ObjectModel> objectModel = typeLookup.lookupObjectModel( type );
            if( objectModel == null )
            {
                return null;
            }
            return objectModel.model();
        }
        catch( ClassNotFoundException e )
        {
            return null;
        }
    }

    @Override
    public TransientDescriptor transientDescriptor( String name )
    {
        try
        {
            Class<?> type = classLoader().loadClass( name );
            ModelModule<TransientModel> transientModel = typeLookup.lookupTransientModel( type );
            if( transientModel == null )
            {
                return null;
            }
            return transientModel.model();
        }
        catch( ClassNotFoundException e )
        {
            return null;
        }
    }

    @Override
    public ValueDescriptor valueDescriptor( String name )
    {
        try
        {
            Class<?> type = classLoader().loadClass( name );
            ModelModule<ValueModel> valueModel = typeLookup.lookupValueModel( type );
            if( valueModel == null )
            {
                return null;
            }
            return valueModel.model();
        }
        catch( ClassNotFoundException e )
        {
            return null;
        }
    }

    // Implementation of MetaInfoHolder
    @Override
    public <T> T metaInfo( Class<T> infoType )
    {
        return model.metaInfo( infoType );
    }

    // Implementation of ObjectFactory
    @Override
    public <T> T newObject( Class<T> mixinType, Object... uses )
        throws NoSuchObjectException
    {
        NullArgumentException.validateNotNull( "mixinType", mixinType );
        ModelModule<ObjectModel> modelModule = typeLookup.lookupObjectModel( mixinType );

        if( modelModule == null )
        {
            throw new NoSuchObjectException( mixinType.getName(), name() );
        }

        InjectionContext injectionContext = new InjectionContext( modelModule.module(), UsesInstance.EMPTY_USES.use( uses ) );
        return mixinType.cast( modelModule.model().newInstance( injectionContext ) );
    }

    @Override
    public void injectTo( Object instance, Object... uses )
        throws ConstructionException
    {
        NullArgumentException.validateNotNull( "instance", instance );
        ModelModule<ObjectModel> modelModule = typeLookup.lookupObjectModel( instance.getClass() );

        if( modelModule == null )
        {
            throw new NoSuchObjectException( instance.getClass().getName(), name() );
        }

        InjectionContext injectionContext = new InjectionContext( modelModule.module(), UsesInstance.EMPTY_USES.use( uses ) );
        modelModule.model().inject( injectionContext, instance );
    }

    // Implementation of TransientBuilderFactory
    @Override
    public <T> TransientBuilder<T> newTransientBuilder( Class<T> mixinType )
        throws NoSuchTransientException
    {
        NullArgumentException.validateNotNull( "mixinType", mixinType );
        ModelModule<TransientModel> modelModule = typeLookup.lookupTransientModel( mixinType );

        if( modelModule == null )
        {
            throw new NoSuchTransientException( mixinType.getName(), name() );
        }

        Map<AccessibleObject, Property<?>> properties = new HashMap<>();
        for( PropertyModel propertyModel : modelModule.model().state().properties() )
        {
            Property<?> property = new PropertyInstance<>( propertyModel.getBuilderInfo(),
                                                           propertyModel.initialValue( modelModule.module() ) );
            properties.put( propertyModel.accessor(), property );
        }

        TransientStateInstance state = new TransientStateInstance( properties );

        return new TransientBuilderInstance<>( modelModule, state, UsesInstance.EMPTY_USES );
    }

    @Override
    public <T> T newTransient( final Class<T> mixinType, Object... uses )
        throws NoSuchTransientException, ConstructionException
    {
        return newTransientBuilder( mixinType ).use( uses ).newInstance();
    }

    // Implementation of ValueBuilderFactory
    @Override
    public <T> T newValue( Class<T> mixinType )
        throws NoSuchValueException, ConstructionException
    {
        return newValueBuilder( mixinType ).newInstance();
    }

    @Override
    public <T> ValueBuilder<T> newValueBuilder( Class<T> mixinType )
        throws NoSuchValueException
    {
        NullArgumentException.validateNotNull( "mixinType", mixinType );
        ModelModule<ValueModel> compositeModelModule = typeLookup.lookupValueModel( mixinType );

        if( compositeModelModule == null )
        {
            throw new NoSuchValueException( mixinType.getName(), name() );
        }

        StateResolver stateResolver = new InitialStateResolver( compositeModelModule.module() );
        return new ValueBuilderInstance<>( compositeModelModule, this, stateResolver );
    }

    @Override
    public <T> ValueBuilder<T> newValueBuilderWithState( Class<T> mixinType,
                                                         Function<PropertyDescriptor, Object> propertyFunction,
                                                         Function<AssociationDescriptor, EntityReference> associationFunction,
                                                         Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
                                                         Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
    )
    {
        NullArgumentException.validateNotNull( "propertyFunction", propertyFunction );
        NullArgumentException.validateNotNull( "associationFunction", associationFunction );
        NullArgumentException.validateNotNull( "manyAssociationFunction", manyAssociationFunction );
        NullArgumentException.validateNotNull( "namedAssociationFunction", namedAssociationFunction );

        ModelModule<ValueModel> compositeModelModule = typeLookup.lookupValueModel( mixinType );

        if( compositeModelModule == null )
        {
            throw new NoSuchValueException( mixinType.getName(), name() );
        }

        StateResolver stateResolver = new FunctionStateResolver(
            propertyFunction, associationFunction, manyAssociationFunction, namedAssociationFunction
        );
        return new ValueBuilderWithState<>( compositeModelModule, this, stateResolver );
    }

    private static class InitialStateResolver
        implements StateResolver
    {
        private final Module module;

        private InitialStateResolver( Module module )
        {
            this.module = module;
        }

        @Override
        public Object getPropertyState( PropertyDescriptor propertyDescriptor )
        {
            return propertyDescriptor.initialValue( module );
        }

        @Override
        public EntityReference getAssociationState( AssociationDescriptor associationDescriptor )
        {
            return null;
        }

        @Override
        public List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
        {
            return new ArrayList<>();
        }

        @Override
        public Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor )
        {
            return new HashMap<>();
        }
    }

    @Override
    @SuppressWarnings( "unchecked" )
    public <T> ValueBuilder<T> newValueBuilderWithPrototype( T prototype )
    {
        NullArgumentException.validateNotNull( "prototype", prototype );

        ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) prototype );
        Class<Composite> valueType = (Class<Composite>) first( valueInstance.types() );

        ModelModule<ValueModel> modelModule = typeLookup.lookupValueModel( valueType );

        if( modelModule == null )
        {
            throw new NoSuchValueException( valueType.getName(), name() );
        }

        return new ValueBuilderWithPrototype<>( modelModule, this, prototype );
    }

    @Override
    public <T> T newValueFromSerializedState( Class<T> mixinType, String serializedState )
        throws NoSuchValueException, ConstructionException
    {
        NullArgumentException.validateNotNull( "mixinType", mixinType );
        ModelModule<ValueModel> modelModule = typeLookup.lookupValueModel( mixinType );

        if( modelModule == null )
        {
            throw new NoSuchValueException( mixinType.getName(), name() );
        }

        try
        {
            return valueSerialization().deserialize( modelModule.model().valueType(), serializedState );
        }
        catch( ValueSerializationException ex )
        {
            throw new ConstructionException( "Could not create value from serialized state", ex );
        }
    }

    // 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 )
    {
        return queryBuilderFactory.newQueryBuilder( resultType );
    }

    // Implementation of ServiceFinder
    @Override
    public <T> ServiceReference<T> findService( Class<T> serviceType )
    {
        return typeLookup.lookupServiceReference( (Type) serviceType );
    }

    @Override
    public <T> ServiceReference<T> findService( Type serviceType )
    {
        return typeLookup.lookupServiceReference( serviceType );
    }

    @Override
    public <T> Iterable<ServiceReference<T>> findServices( Class<T> serviceType )
    {
        return typeLookup.lookupServiceReferences( (Type) serviceType );
    }

    @Override
    public <T> Iterable<ServiceReference<T>> findServices( Type serviceType )
    {
        return typeLookup.lookupServiceReferences( serviceType );
    }

    // Implementation of Activation
    @Override
    @SuppressWarnings( "unchecked" )
    public void activate()
        throws ActivationException
    {
        activation.activate( model.newActivatorsInstance(), iterable( services, importedServices ) );
    }

    @Override
    public void passivate()
        throws PassivationException
    {
        activation.passivate();
    }

    @Override
    public void registerActivationEventListener( ActivationEventListener listener )
    {
        activation.registerActivationEventListener( listener );
    }

    @Override
    public void deregisterActivationEventListener( ActivationEventListener listener )
    {
        activation.deregisterActivationEventListener( listener );
    }

    // Other methods
    /* package */ ModuleModel model()
    {
        return model;
    }

    public LayerInstance layerInstance()
    {
        return layer;
    }

    public TypeLookup typeLookup()
    {
        return typeLookup;
    }

    public Function2<EntityReference, Type, Object> getEntityFunction()
    {
        return entityFunction;
    }

    private static class EntityFunction
        implements Function2<EntityReference, Type, Object>
    {

        private final UnitOfWorkFactory uowf;

        private EntityFunction( UnitOfWorkFactory uowf )
        {
            this.uowf = uowf;
        }

        @Override
        public Object map( EntityReference entityReference, Type type )
        {
            return uowf.currentUnitOfWork().get( RAW_CLASS.map( type ), entityReference.identity() );
        }
    }

    public EntityStore entityStore()
    {
        synchronized( this )
        {
            if( store == null )
            {
                ServiceReference<EntityStore> service = findService( EntityStore.class );
                if( service == null )
                {
                    throw new UnitOfWorkException( "No EntityStore service available in module " + name() );
                }
                store = service.get();
            }
        }
        return store;
    }

    public IdentityGenerator identityGenerator()
    {
        synchronized( this )
        {
            if( generator == null )
            {
                ServiceReference<IdentityGenerator> service = findService( IdentityGenerator.class );
                generator = service.get();
            }
            return generator;
        }
    }

    public ValueSerialization valueSerialization()
    {
        synchronized( this )
        {
            if( valueSerialization == null )
            {
                try
                {
                    ServiceReference<ValueSerialization> service = findService( ValueSerialization.class );
                    valueSerialization = service.get();
                }
                catch( NoSuchServiceException e )
                {
//                    valueSerialization = newObject( OrgJsonValueSerialization.class );
                    valueSerialization = new OrgJsonValueSerialization( layer.applicationInstance(), this, this );
                }
            }
        }
        return valueSerialization;
    }

    /* package */ MetricsProvider metricsProvider()
    {
        synchronized( this )
        {
            if( metrics == null )
            {
                try
                {
                    ServiceReference<MetricsProvider> service = findService( MetricsProvider.class );
                    metrics = service.get();
                }
                catch( NoSuchServiceException e )
                {
                    metrics = new MetricsProviderAdapter();
                }
            }
        }
        return metrics;
    }

    public Iterable<ModelModule<ObjectDescriptor>> visibleObjects( Visibility visibility )
    {
        return map( ModelModule.<ObjectDescriptor>modelModuleFunction( this ),
                    filter( new VisibilitySpecification( visibility ), objects.models() ) );
    }

    public Iterable<ModelModule<TransientDescriptor>> visibleTransients( Visibility visibility )
    {
        return map( ModelModule.<TransientDescriptor>modelModuleFunction( this ),
                    filter( new VisibilitySpecification( visibility ), transients.models() ) );
    }

    public Iterable<ModelModule<EntityDescriptor>> visibleEntities( Visibility visibility )
    {
        return map( ModelModule.<EntityDescriptor>modelModuleFunction( this ),
                    filter( new VisibilitySpecification( visibility ), entities.models() ) );
    }

    public Iterable<ModelModule<ValueDescriptor>> visibleValues( Visibility visibility )
    {
        return map( ModelModule.<ValueDescriptor>modelModuleFunction( this ),
                    filter( new VisibilitySpecification( visibility ), values.models() ) );
    }

    public Iterable<ServiceReference<?>> visibleServices( Visibility visibility )
    {
        return flatten( services.visibleServices( visibility ),
                        importedServices.visibleServices( visibility ) );
    }

    // Module ClassLoader
    private static class ModuleClassLoader
        extends ClassLoader
    {

        private final ModuleInstance moduleInstance;
        private final Map<String, Class<?>> classes = new ConcurrentHashMap<>();

        private ModuleClassLoader( ModuleInstance moduleInstance, ClassLoader classLoader )
        {
            super( classLoader );
            this.moduleInstance = moduleInstance;
        }

        @Override
        protected Class<?> findClass( String name )
            throws ClassNotFoundException
        {
            Class<?> clazz = classes.get( name );
            if( clazz == null )
            {
                Specification<ModelDescriptor> modelTypeSpecification = modelTypeSpecification( name );
                Specification<ModelModule<ModelDescriptor>> translate = Specifications.translate( ModelModule.modelFunction(), modelTypeSpecification );
                // Check module
                {
                    Iterable<ModelModule<ModelDescriptor>> i = cast( flatten(
                        cast( moduleInstance.visibleObjects( Visibility.module ) ),
                        cast( moduleInstance.visibleEntities( Visibility.module ) ),
                        cast( moduleInstance.visibleTransients( Visibility.module ) ),
                        cast( moduleInstance.visibleValues( Visibility.module ) ) ) );

                    Iterable<ModelModule<ModelDescriptor>> moduleModels = filter( translate, i );
                    Iterator<ModelModule<ModelDescriptor>> iter = moduleModels.iterator();
                    if( iter.hasNext() )
                    {
                        clazz = first( iter.next().model().types() );

                        if( iter.hasNext() )
                        {
                            // Ambiguous exception
                            throw new ClassNotFoundException(
                                name,
                                new AmbiguousTypeException(
                                    "More than one model matches the classname " + name + ":" + toList( moduleModels )
                                )
                            );
                        }
                    }
                }

                // Check layer
                if( clazz == null )
                {
                    Iterable<ModelModule<ModelDescriptor>> flatten = cast( flatten(
                        cast( moduleInstance.layerInstance().visibleObjects( Visibility.layer ) ),
                        cast( moduleInstance.layerInstance().visibleTransients( Visibility.layer ) ),
                        cast( moduleInstance.layerInstance().visibleEntities( Visibility.layer ) ),
                        cast( moduleInstance.layerInstance().visibleValues( Visibility.layer ) ),
                        cast( moduleInstance.layerInstance().visibleObjects( Visibility.application ) ),
                        cast( moduleInstance.layerInstance().visibleTransients( Visibility.application ) ),
                        cast( moduleInstance.layerInstance().visibleEntities( Visibility.application ) ),
                        cast( moduleInstance.layerInstance().visibleValues( Visibility.application ) ) ) );
                    Iterable<ModelModule<ModelDescriptor>> layerModels = filter( translate, flatten );
                    Iterator<ModelModule<ModelDescriptor>> iter = layerModels.iterator();
                    if( iter.hasNext() )
                    {
                        clazz = first( iter.next().model().types() );

                        if( iter.hasNext() )
                        {
                            // Ambiguous exception
                            throw new ClassNotFoundException(
                                name,
                                new AmbiguousTypeException(
                                    "More than one model matches the classname " + name + ":" + toList( layerModels ) )
                            );
                        }
                    }
                }

                // Check used layers
                if( clazz == null )
                {
                    Iterable<ModelModule<ModelDescriptor>> flatten = cast( flatten(
                        cast( moduleInstance.layerInstance().usedLayersInstance().visibleObjects() ),
                        cast( moduleInstance.layerInstance().usedLayersInstance().visibleTransients() ),
                        cast( moduleInstance.layerInstance().usedLayersInstance().visibleEntities() ),
                        cast( moduleInstance.layerInstance().usedLayersInstance().visibleValues() ) ) );
                    Iterable<ModelModule<ModelDescriptor>> usedLayersModels = filter( translate, flatten );
                    Iterator<ModelModule<ModelDescriptor>> iter = usedLayersModels.iterator();
                    if( iter.hasNext() )
                    {
                        clazz = first( iter.next().model().types() );

                        if( iter.hasNext() )
                        {
                            // Ambiguous exception
                            throw new ClassNotFoundException(
                                name,
                                new AmbiguousTypeException(
                                    "More than one model matches the classname " + name + ":" + toList( usedLayersModels )
                                )
                            );
                        }
                    }
                }

                if( clazz == null )
                {
                    throw new ClassNotFoundException( name );
                }
                classes.put( name, clazz );
            }

            return clazz;
        }
    }

    public Iterable<ModelModule<ValueDescriptor>> findVisibleValueTypes()
    {
        return flatten( visibleValues( Visibility.module ),
            layerInstance().visibleValues( Visibility.layer ),
            layerInstance().visibleValues( Visibility.application ),
            layerInstance().usedLayersInstance().visibleValues()
        );
    }

    public Iterable<ModelModule<EntityDescriptor>> findVisibleEntityTypes()
    {
        return flatten( visibleEntities( Visibility.module ),
            layerInstance().visibleEntities( Visibility.layer ),
            layerInstance().visibleEntities( Visibility.application ),
            layerInstance().usedLayersInstance().visibleEntities()
        );
    }
    public Iterable<ModelModule<TransientDescriptor>> findVisibleTransientTypes()
    {
        return flatten( visibleTransients( Visibility.module ),
            layerInstance().visibleTransients( Visibility.layer ),
            layerInstance().visibleTransients( Visibility.application ),
            layerInstance().usedLayersInstance().visibleTransients()
        );
    }
    public Iterable<ModelModule<ServiceDescriptor>> findVisibleServiceTypes()
    {
        return flatten( visibleServices( Visibility.module ),
            layerInstance().visibleServices( Visibility.layer ),
            layerInstance().visibleServices( Visibility.application ),
            layerInstance().usedLayersInstance().visibleServices()
        );
    }
    public Iterable<ModelModule<ObjectDescriptor>> findVisibleObjectTypes()
    {
        return flatten( visibleObjects( Visibility.module ),
            layerInstance().visibleObjects( Visibility.layer ),
            layerInstance().visibleObjects( Visibility.application ),
            layerInstance().usedLayersInstance().visibleObjects()
        );
    }
}
