/*******************************************************************************
 * Copyright (c) 2010-present Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
 *
 * Minimal facade required to be binary-compatible with legacy Plexus API
 *******************************************************************************/
package org.codehaus.plexus;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import javax.inject.Provider;

import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextMapAdapter;
import org.codehaus.plexus.context.DefaultContext;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.LoggerManager;
import org.codehaus.plexus.logging.console.ConsoleLoggerManager;
import org.eclipse.sisu.bean.BeanManager;
import org.eclipse.sisu.bean.LifecycleManager;
import org.eclipse.sisu.inject.DefaultBeanLocator;
import org.eclipse.sisu.inject.DefaultRankingFunction;
import org.eclipse.sisu.inject.DeferredClass;
import org.eclipse.sisu.inject.DeferredProvider;
import org.eclipse.sisu.inject.InjectorBindings;
import org.eclipse.sisu.inject.MutableBeanLocator;
import org.eclipse.sisu.inject.RankingFunction;
import org.eclipse.sisu.plexus.ComponentDescriptorBeanModule;
import org.eclipse.sisu.plexus.DefaultPlexusBeanLocator;
import org.eclipse.sisu.plexus.Hints;
import org.eclipse.sisu.plexus.PlexusAnnotatedBeanModule;
import org.eclipse.sisu.plexus.PlexusBean;
import org.eclipse.sisu.plexus.PlexusBeanConverter;
import org.eclipse.sisu.plexus.PlexusBeanLocator;
import org.eclipse.sisu.plexus.PlexusBeanModule;
import org.eclipse.sisu.plexus.PlexusBindingModule;
import org.eclipse.sisu.plexus.PlexusDateTypeConverter;
import org.eclipse.sisu.plexus.PlexusLifecycleManager;
import org.eclipse.sisu.plexus.PlexusXmlBeanConverter;
import org.eclipse.sisu.plexus.PlexusXmlBeanModule;
import org.eclipse.sisu.plexus.RealmManager;
import org.eclipse.sisu.space.BeanScanning;
import org.eclipse.sisu.space.ClassSpace;
import org.eclipse.sisu.space.LoadedClass;
import org.eclipse.sisu.space.URLClassSpace;
import org.eclipse.sisu.wire.EntryListAdapter;
import org.eclipse.sisu.wire.EntryMapAdapter;
import org.eclipse.sisu.wire.MergedModule;
import org.eclipse.sisu.wire.ParameterKeys;
import org.eclipse.sisu.wire.WireModule;

import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import com.google.inject.util.Providers;

/**
 * {@link PlexusContainer} shim that delegates to a Plexus-aware Guice {@link Injector}.
 */
@SuppressWarnings( { "unchecked", "rawtypes" } )
public final class DefaultPlexusContainer
    implements MutablePlexusContainer
{
    // ----------------------------------------------------------------------
    // Static initialization
    // ----------------------------------------------------------------------

    static
    {
        System.setProperty( "guice.disable.misplaced.annotation.check", "true" );
    }

    // ----------------------------------------------------------------------
    // Constants
    // ----------------------------------------------------------------------

    private static final String DEFAULT_REALM_NAME = "plexus.core";

    private static final Module[] NO_CUSTOM_MODULES = {};

    // ----------------------------------------------------------------------
    // Implementation fields
    // ----------------------------------------------------------------------

    final AtomicInteger plexusRank = new AtomicInteger();

    final Map<ClassRealm, List<ComponentDescriptor<?>>> descriptorMap =
        new IdentityHashMap<ClassRealm, List<ComponentDescriptor<?>>>();

    final ThreadLocal<ClassRealm> lookupRealm = new ThreadLocal<ClassRealm>();

    final LoggerManagerProvider loggerManagerProvider = new LoggerManagerProvider();

    final MutableBeanLocator qualifiedBeanLocator = new DefaultBeanLocator();

    final Context context;

    final Map<?, ?> variables;

    final ClassRealm containerRealm;

    final RealmManager realmManager;

    final PlexusBeanLocator plexusBeanLocator;

    final BeanManager plexusBeanManager;

    private final String componentVisibility;

    private final boolean isAutoWiringEnabled;

    private final BeanScanning scanning;

    private final Module containerModule = new ContainerModule();

    private final Module defaultsModule = new DefaultsModule();

    private LoggerManager loggerManager = new ConsoleLoggerManager();

    private Logger logger;

    private boolean disposing;

    // ----------------------------------------------------------------------
    // Constructors
    // ----------------------------------------------------------------------

    public DefaultPlexusContainer()
        throws PlexusContainerException
    {
        this( new DefaultContainerConfiguration() );
    }

    public DefaultPlexusContainer( final ContainerConfiguration configuration )
        throws PlexusContainerException
    {
        this( configuration, NO_CUSTOM_MODULES );
    }

    @SuppressWarnings( "finally" )
    public DefaultPlexusContainer( final ContainerConfiguration configuration, final Module... customModules )
        throws PlexusContainerException
    {
        final URL plexusXml = lookupPlexusXml( configuration );

        context = getContextComponent( configuration );
        context.put( PlexusConstants.PLEXUS_KEY, this );
        variables = new ContextMapAdapter( context );

        containerRealm = lookupContainerRealm( configuration );
        realmManager = new RealmManager( qualifiedBeanLocator );
        containerRealm.getWorld().addListener( realmManager );

        componentVisibility = configuration.getComponentVisibility();
        isAutoWiringEnabled = configuration.getAutoWiring();

        scanning = parseScanningOption( configuration.getClassPathScanning() );

        plexusBeanLocator = new DefaultPlexusBeanLocator( qualifiedBeanLocator, realmManager, componentVisibility );
        final BeanManager jsr250Lifecycle = configuration.getJSR250Lifecycle() ? new LifecycleManager() : null;
        plexusBeanManager = new PlexusLifecycleManager( Providers.of( context ), loggerManagerProvider, //
                                                        new SLF4JLoggerFactoryProvider(), jsr250Lifecycle );

        setLookupRealm( containerRealm );

        final List<PlexusBeanModule> beanModules = new ArrayList<PlexusBeanModule>();

        final ClassSpace space = new URLClassSpace( containerRealm );
        beanModules.add( new PlexusXmlBeanModule( space, variables, plexusXml ) );
        final BeanScanning global = BeanScanning.INDEX == scanning ? BeanScanning.GLOBAL_INDEX : scanning;
        beanModules.add( new PlexusAnnotatedBeanModule( space, variables, global ) );

        try
        {
            addPlexusInjector( beanModules, new BootModule( customModules ) );
        }
        catch ( final RuntimeException e )
        {
            try
            {
                dispose(); // cleanup as much as possible
            }
            finally
            {
                throw e; // always report original failure
            }
        }
    }

    // ----------------------------------------------------------------------
    // Context methods
    // ----------------------------------------------------------------------

    public Context getContext()
    {
        return context;
    }

    // ----------------------------------------------------------------------
    // Lookup methods
    // ----------------------------------------------------------------------

    public Object lookup( final String role )
        throws ComponentLookupException
    {
        return lookup( role, "" );
    }

    public Object lookup( final String role, final String hint )
        throws ComponentLookupException
    {
        return lookup( null, role, hint );
    }

    public <T> T lookup( final Class<T> role )
        throws ComponentLookupException
    {
        return lookup( role, "" );
    }

    public <T> T lookup( final Class<T> role, final String hint )
        throws ComponentLookupException
    {
        return lookup( role, null, hint );
    }

    public <T> T lookup( final Class<T> type, final String role, final String hint )
        throws ComponentLookupException
    {
        try
        {
            return locate( role, type, hint ).iterator().next().getValue();
        }
        catch ( final RuntimeException e )
        {
            throw new ComponentLookupException( e, null != type ? type.getName() : role, hint );
        }
    }

    public List<Object> lookupList( final String role )
        throws ComponentLookupException
    {
        return new EntryListAdapter<Object>( locate( role, null ) );
    }

    public <T> List<T> lookupList( final Class<T> role )
        throws ComponentLookupException
    {
        return new EntryListAdapter<T>( locate( null, role ) );
    }

    public Map<String, Object> lookupMap( final String role )
        throws ComponentLookupException
    {
        return new EntryMapAdapter<String, Object>( locate( role, null ) );
    }

    public <T> Map<String, T> lookupMap( final Class<T> role )
        throws ComponentLookupException
    {
        return new EntryMapAdapter<String, T>( locate( null, role ) );
    }

    // ----------------------------------------------------------------------
    // Query methods
    // ----------------------------------------------------------------------

    public boolean hasComponent( final String role )
    {
        return hasComponent( role, "" );
    }

    public boolean hasComponent( final String role, final String hint )
    {
        return hasComponent( null, role, hint );
    }

    public boolean hasComponent( final Class role )
    {
        return hasComponent( role, "" );
    }

    public boolean hasComponent( final Class role, final String hint )
    {
        return hasComponent( role, null, hint );
    }

    public boolean hasComponent( final Class type, final String role, final String hint )
    {
        return hasPlexusBeans( locate( role, type, hint ) );
    }

    // ----------------------------------------------------------------------
    // Component descriptor methods
    // ----------------------------------------------------------------------

    public void addComponent( final Object component, final String role )
    {
        try
        {
            addComponent( component, component.getClass().getClassLoader().loadClass( role ), Hints.DEFAULT_HINT );
        }
        catch ( final ClassNotFoundException e )
        {
            throw new TypeNotPresentException( role, e );
        }
    }

    public <T> void addComponent( final T component, final Class<?> role, final String hint )
    {
        // this is only used in Maven3 tests, so keep it simple...
        qualifiedBeanLocator.add( new InjectorBindings( Guice.createInjector( new Module()
        {
            public void configure( final Binder binder )
            {
                if ( Hints.isDefaultHint( hint ) )
                {
                    binder.bind( (Class) role ).toInstance( component );
                }
                else
                {
                    binder.bind( (Class) role ).annotatedWith( Names.named( hint ) ).toInstance( component );
                }
            }
        } ), new DefaultRankingFunction( plexusRank.incrementAndGet() ) ) );
    }

    public <T> void addComponentDescriptor( final ComponentDescriptor<T> descriptor )
    {
        ClassRealm realm = descriptor.getRealm();
        if ( null == realm )
        {
            realm = containerRealm;
            descriptor.setRealm( realm );
        }
        synchronized ( descriptorMap )
        {
            List<ComponentDescriptor<?>> descriptors = descriptorMap.get( realm );
            if ( null == descriptors )
            {
                descriptors = new ArrayList<ComponentDescriptor<?>>();
                descriptorMap.put( realm, descriptors );
            }
            descriptors.add( descriptor );
        }
        if ( containerRealm == realm )
        {
            discoverComponents( containerRealm ); // for Maven3 testing
        }
    }

    public ComponentDescriptor<?> getComponentDescriptor( final String role, final String hint )
    {
        return getComponentDescriptor( null, role, hint );
    }

    public <T> ComponentDescriptor<T> getComponentDescriptor( final Class<T> type, final String role,
                                                              final String hint )
    {
        final Iterator<PlexusBean<T>> i = locate( role, type, hint ).iterator();
        if ( i.hasNext() )
        {
            final PlexusBean<T> bean = i.next();
            if ( bean.getImplementationClass() != null )
            {
                return newComponentDescriptor( role, bean );
            }
        }
        return null;
    }

    public List getComponentDescriptorList( final String role )
    {
        return getComponentDescriptorList( null, role );
    }

    public <T> List<ComponentDescriptor<T>> getComponentDescriptorList( final Class<T> type, final String role )
    {
        final List<ComponentDescriptor<T>> tempList = new ArrayList<ComponentDescriptor<T>>();
        for ( final PlexusBean<T> bean : locate( role, type ) )
        {
            tempList.add( newComponentDescriptor( role, bean ) );
        }
        return tempList;
    }

    public Map getComponentDescriptorMap( final String role )
    {
        return getComponentDescriptorMap( null, role );
    }

    public <T> Map<String, ComponentDescriptor<T>> getComponentDescriptorMap( final Class<T> type, final String role )
    {
        final Map<String, ComponentDescriptor<T>> tempMap = new LinkedHashMap<String, ComponentDescriptor<T>>();
        for ( final PlexusBean<T> bean : locate( role, type ) )
        {
            tempMap.put( bean.getKey(), newComponentDescriptor( role, bean ) );
        }
        return tempMap;
    }

    public List<ComponentDescriptor<?>> discoverComponents( final ClassRealm realm )
    {
        return discoverComponents( realm, NO_CUSTOM_MODULES );
    }

    public List<ComponentDescriptor<?>> discoverComponents( final ClassRealm realm, final Module... customModules )
    {
        try
        {
            final List<PlexusBeanModule> beanModules = new ArrayList<PlexusBeanModule>();
            synchronized ( descriptorMap )
            {
                final ClassSpace space = new URLClassSpace( realm );
                final List<ComponentDescriptor<?>> descriptors = descriptorMap.remove( realm );
                if ( null != descriptors )
                {
                    beanModules.add( new ComponentDescriptorBeanModule( space, descriptors ) );
                }
                if ( containerRealm != realm && !realmManager.isManaged( realm ) )
                {
                    beanModules.add( new PlexusXmlBeanModule( space, variables ) );
                    final BeanScanning local = BeanScanning.GLOBAL_INDEX == scanning ? BeanScanning.INDEX : scanning;
                    beanModules.add( new PlexusAnnotatedBeanModule( space, variables, local ) );
                }
            }
            if ( !beanModules.isEmpty() )
            {
                realmManager.manage( realm, addPlexusInjector( beanModules, customModules ) );
            }
        }
        catch ( final RuntimeException e )
        {
            getLogger().warn( realm.toString(), e );
        }

        return null; // no-one actually seems to use or check the returned component list!
    }

    public Injector addPlexusInjector( final List<? extends PlexusBeanModule> beanModules,
                                       final Module... customModules )
    {
        final List<Module> modules = new ArrayList<Module>();

        modules.add( containerModule );
        Collections.addAll( modules, customModules );
        modules.add( new PlexusBindingModule( plexusBeanManager, beanModules ) );
        modules.add( defaultsModule );

        return Guice.createInjector( isAutoWiringEnabled ? new WireModule( modules ) : new MergedModule( modules ) );
    }

    // ----------------------------------------------------------------------
    // Class realm methods
    // ----------------------------------------------------------------------

    public ClassWorld getClassWorld()
    {
        return containerRealm.getWorld();
    }

    public ClassRealm getContainerRealm()
    {
        return containerRealm;
    }

    public ClassRealm setLookupRealm( final ClassRealm realm )
    {
        final ClassRealm oldRealm = lookupRealm.get();
        lookupRealm.set( realm );
        return oldRealm;
    }

    public ClassRealm getLookupRealm()
    {
        return lookupRealm.get();
    }

    public ClassRealm createChildRealm( final String id )
    {
        try
        {
            return containerRealm.createChildRealm( id );
        }
        catch ( final DuplicateRealmException e1 )
        {
            try
            {
                return getClassWorld().getRealm( id );
            }
            catch ( final NoSuchRealmException e2 )
            {
                return null; // should never happen!
            }
        }
    }

    // ----------------------------------------------------------------------
    // Logger methods
    // ----------------------------------------------------------------------

    public synchronized LoggerManager getLoggerManager()
    {
        return loggerManager;
    }

    @Inject( optional = true )
    public synchronized void setLoggerManager( final LoggerManager loggerManager )
    {
        if ( null != loggerManager )
        {
            this.loggerManager = loggerManager;
        }
        else
        {
            this.loggerManager = new ConsoleLoggerManager();
        }
        logger = null; // refresh our local logger
    }

    public synchronized Logger getLogger()
    {
        if ( null == logger )
        {
            logger = loggerManager.getLoggerForComponent( PlexusContainer.class.getName(), null );
        }
        return logger;
    }

    // ----------------------------------------------------------------------
    // Shutdown methods
    // ----------------------------------------------------------------------

    public void release( final Object component )
    {
        plexusBeanManager.unmanage( component );
    }

    public void releaseAll( final Map<String, ?> components )
    {
        for ( final Object o : components.values() )
        {
            release( o );
        }
    }

    public void releaseAll( final List<?> components )
    {
        for ( final Object o : components )
        {
            release( o );
        }
    }

    public void dispose()
    {
        disposing = true;

        plexusBeanManager.unmanage();
        containerRealm.setParentRealm( null );
        qualifiedBeanLocator.clear();

        lookupRealm.remove();

        containerRealm.getWorld().removeListener( realmManager );
    }

    // ----------------------------------------------------------------------
    // Implementation methods
    // ----------------------------------------------------------------------

    private static BeanScanning parseScanningOption( final String scanning )
    {
        for ( final BeanScanning option : BeanScanning.values() )
        {
            if ( option.name().equalsIgnoreCase( scanning ) )
            {
                return option;
            }
        }
        return BeanScanning.OFF;
    }

    /**
     * Finds container {@link ClassRealm}, taking existing {@link ClassWorld}s or {@link ClassLoader}s into account.
     * 
     * @param configuration The container configuration
     * @return Container class realm
     */
    private static ClassRealm lookupContainerRealm( final ContainerConfiguration configuration )
        throws PlexusContainerException
    {
        ClassRealm realm = configuration.getRealm();
        if ( null == realm )
        {
            ClassWorld world = configuration.getClassWorld();
            if ( null == world )
            {
                world = new ClassWorld( DEFAULT_REALM_NAME, Thread.currentThread().getContextClassLoader() );
            }
            try
            {
                realm = world.getRealm( DEFAULT_REALM_NAME );
            }
            catch ( final NoSuchRealmException e )
            {
                final Iterator<?> realmIterator = world.getRealms().iterator();
                if ( realmIterator.hasNext() )
                {
                    realm = (ClassRealm) realmIterator.next();
                }
            }
        }
        if ( null == realm )
        {
            throw new PlexusContainerException( "Missing container class realm: " + DEFAULT_REALM_NAME );
        }
        return realm;
    }

    /**
     * Finds container configuration URL, may search the container {@link ClassRealm} and local file-system.
     * 
     * @param configuration The container configuration
     * @return Local or remote URL
     */
    private URL lookupPlexusXml( final ContainerConfiguration configuration )
    {
        URL url = configuration.getContainerConfigurationURL();
        if ( null == url )
        {
            final String configurationPath = configuration.getContainerConfiguration();
            if ( null != configurationPath )
            {
                int index = 0;
                while ( index < configurationPath.length() && configurationPath.charAt( index ) == '/' )
                {
                    index++;
                }

                url = getClass().getClassLoader().getResource( configurationPath.substring( index ) );
                if ( null == url )
                {
                    final File file = new File( configurationPath );
                    if ( file.isFile() )
                    {
                        try
                        {
                            url = file.toURI().toURL();
                        }
                        catch ( final MalformedURLException e ) // NOPMD
                        {
                            // drop through and recover
                        }
                    }
                }
                if ( null == url )
                {
                    getLogger().debug( "Missing container configuration: " + configurationPath );
                }
            }
        }
        return url;
    }

    private static Context getContextComponent( final ContainerConfiguration configuration )
    {
        final Map<?, ?> contextData = configuration.getContext();
        final Context contextComponent = configuration.getContextComponent();
        if ( null == contextComponent )
        {
            return new DefaultContext( contextData );
        }
        if ( null != contextData )
        {
            for ( final Entry<?, ?> entry : contextData.entrySet() )
            {
                contextComponent.put( entry.getKey(), entry.getValue() );
            }
        }
        return contextComponent;
    }

    private <T> Iterable<PlexusBean<T>> locate( final String role, final Class<T> type, final String... hints )
    {
        if ( disposing )
        {
            return Collections.EMPTY_SET;
        }
        final String[] canonicalHints = Hints.canonicalHints( hints );
        if ( null == role || null != type && type.getName().equals( role ) )
        {
            return plexusBeanLocator.locate( TypeLiteral.get( type ), canonicalHints );
        }
        final Set<Class> candidates = new HashSet<Class>();
        for ( final ClassRealm realm : getVisibleRealms() )
        {
            try
            {
                final Class clazz = realm.loadClass( role );
                if ( candidates.add( clazz ) )
                {
                    final Iterable beans = plexusBeanLocator.locate( TypeLiteral.get( clazz ), canonicalHints );
                    if ( hasPlexusBeans( beans ) )
                    {
                        return beans;
                    }
                }
            }
            catch ( final Exception e )
            {
                // drop through...
            }
            catch ( final LinkageError e )
            {
                // drop through...
            }
        }
        return Collections.EMPTY_SET;
    }

    private Collection<ClassRealm> getVisibleRealms()
    {
        final Object[] realms = getClassWorld().getRealms().toArray();
        final Set<ClassRealm> visibleRealms = new LinkedHashSet<ClassRealm>( realms.length );
        final ClassRealm currentLookupRealm = getLookupRealm();
        if ( null != currentLookupRealm )
        {
            visibleRealms.add( currentLookupRealm );
        }
        final ClassRealm threadContextRealm = RealmManager.contextRealm();
        if ( null != threadContextRealm )
        {
            visibleRealms.add( threadContextRealm );
        }
        if ( PlexusConstants.REALM_VISIBILITY.equalsIgnoreCase( componentVisibility ) )
        {
            final Collection<String> realmNames = realmManager.visibleRealmNames( threadContextRealm );
            if ( null != realmNames && realmNames.size() > 0 )
            {
                for ( int i = realms.length - 1; i >= 0; i-- )
                {
                    final ClassRealm r = (ClassRealm) realms[i];
                    if ( realmNames.contains( r.toString() ) )
                    {
                        visibleRealms.add( r );
                    }
                }
                return visibleRealms;
            }
        }
        for ( int i = realms.length - 1; i >= 0; i-- )
        {
            visibleRealms.add( (ClassRealm) realms[i] );
        }
        return visibleRealms;
    }

    private static <T> boolean hasPlexusBeans( final Iterable<PlexusBean<T>> beans )
    {
        final Iterator<PlexusBean<T>> i = beans.iterator();
        return i.hasNext() && i.next().getImplementationClass() != null;
    }

    private static <T> ComponentDescriptor<T> newComponentDescriptor( final String role, final PlexusBean<T> bean )
    {
        final ComponentDescriptor<T> cd = new ComponentDescriptor<T>();
        cd.setRole( role );
        cd.setRoleHint( bean.getKey() );
        cd.setImplementationClass( bean.getImplementationClass() );
        cd.setDescription( bean.getDescription() );
        return cd;
    }

    final class BootModule
        implements Module
    {
        private final Module[] customBootModules;

        BootModule( final Module[] customBootModules )
        {
            this.customBootModules = customBootModules;
        }

        public void configure( final Binder binder )
        {
            binder.requestInjection( DefaultPlexusContainer.this );
            for ( final Module m : customBootModules )
            {
                binder.install( m );
            }
        }
    }

    final class ContainerModule
        implements Module
    {
        public void configure( final Binder binder )
        {
            binder.bind( Context.class ).toInstance( context );
            binder.bind( ParameterKeys.PROPERTIES ).toInstance( context.getContextData() );

            binder.bind( MutableBeanLocator.class ).toInstance( qualifiedBeanLocator );
            binder.bind( PlexusBeanLocator.class ).toInstance( plexusBeanLocator );
            binder.bind( BeanManager.class ).toInstance( plexusBeanManager );

            binder.bind( PlexusContainer.class ).to( MutablePlexusContainer.class );
            binder.bind( MutablePlexusContainer.class ).to( DefaultPlexusContainer.class );

            // use provider wrapper to avoid repeated injections later on when configuring plugin injectors
            binder.bind( DefaultPlexusContainer.class ).toProvider( Providers.of( DefaultPlexusContainer.this ) );
        }
    }

    final class DefaultsModule
        implements Module
    {
        private final LoggerProvider loggerProvider = new LoggerProvider();

        private final PlexusDateTypeConverter dateConverter = new PlexusDateTypeConverter();

        public void configure( final Binder binder )
        {
            binder.bind( LoggerManager.class ).toProvider( loggerManagerProvider );
            binder.bind( Logger.class ).toProvider( loggerProvider );

            // allow plugins to override the default ranking function so we can support component profiles
            final Key<RankingFunction> plexusRankingKey = Key.get( RankingFunction.class, Names.named( "plexus" ) );
            binder.bind( plexusRankingKey ).toInstance( new DefaultRankingFunction( plexusRank.incrementAndGet() ) );
            binder.bind( RankingFunction.class ).to( plexusRankingKey );

            binder.install( dateConverter );

            binder.bind( PlexusBeanConverter.class ).to( PlexusXmlBeanConverter.class );
        }
    }

    final class LoggerManagerProvider
        implements DeferredProvider<LoggerManager>
    {
        public LoggerManager get()
        {
            return getLoggerManager();
        }

        public DeferredClass<LoggerManager> getImplementationClass()
        {
            return new LoadedClass<LoggerManager>( get().getClass() );
        }
    }

    final class LoggerProvider
        implements DeferredProvider<Logger>
    {
        public Logger get()
        {
            return getLogger();
        }

        public DeferredClass<Logger> getImplementationClass()
        {
            return new LoadedClass<Logger>( get().getClass() );
        }
    }

    final class SLF4JLoggerFactoryProvider
        implements Provider<Object>
    {
        public Object get()
        {
            return plexusBeanLocator.locate( TypeLiteral.get( org.slf4j.ILoggerFactory.class ) ).iterator().next().getValue();
        }
    }
}
