package picocli.spring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import picocli.CommandLine;

/**
 * @author Thibaud Leprêtre
 */
public class PicocliSpringFactory implements CommandLine.IFactory {
    private static final Logger logger = LoggerFactory.getLogger(PicocliSpringFactory.class);

    private final ApplicationContext applicationContext;

    public PicocliSpringFactory(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public <K> K create(Class<K> clazz) throws Exception {
        try {
            return getBeanOrCreate(clazz);
        } catch (Exception e) {
            logger.warn("Unable to get bean of class {}, using default Picocli factory", clazz);
            return CommandLine.defaultFactory().create(clazz);
        }
    }

    private <K> K getBeanOrCreate(Class<K> clazz) {
        try {
            return applicationContext.getBean(clazz);
        } catch (Exception e) {
            return applicationContext.getAutowireCapableBeanFactory().createBean(clazz);
        }
    }
}

@@ -163,10 +163,414 @@
 e;%0A%0A
-/*
+import java.util.Objects;%0A%0A/**%0A * PicocliSpringFactory is a %7B@link picocli.CommandLine.IFactory%7D implementation that%0A * looks up classes in a given %7B@code org.springframework.context.ApplicationContext%7D.%0A * This allows picocli subcommands (and other objects that are instantiated as needed)%0A * to have %7B@code javax.inject%7D annotations that will be populated%0A * by Spring's dependency injection framework.%0A 
 *%0A *
@@ -595,16 +595,32 @@
 epr%C3%AAtre%0A
+ * @since 4.0.0%0A
  */%0Apubl
@@ -839,134 +839,1369 @@
 xt;%0A
-%0A    public PicocliSpringFactory(ApplicationContext applicationContext) %7B%0A        this.applicationContext = applicationContext
+    private final CommandLine.IFactory fallbackFactory;%0A%0A    /**%0A     * Constructs a PicocliSpringFactory with the specified Application context,%0A     * and picocli's %7B@link CommandLine#defaultFactory() default factory%7D as the fallback factory%0A     * for classes not found in the application context.%0A     * @param applicationContext the application context to look up classes in; must be non-%7B@code null%7D%0A     */%0A    public PicocliSpringFactory(ApplicationContext applicationContext) %7B%0A        this(applicationContext, CommandLine.defaultFactory());%0A    %7D%0A%0A    /**%0A     * Constructs a PicocliSpringFactory with the specified Application context,%0A     * and the specified fallback factory%0A     * for classes not found in the application context.%0A     * @param applicationContext the application context to look up classes in; must be non-%7B@code null%7D%0A     * @param fallbackFactory the factory used to instantiate classes that are%0A     *                        not found in the specified application context; must be non-%7B@code null%7D%0A     * @since 4.7.0%0A     */%0A    public PicocliSpringFactory(ApplicationContext applicationContext, CommandLine.IFactory fallbackFactory) %7B%0A        this.applicationContext = Objects.requireNonNull(applicationContext, %22applicationContext%22);%0A        this.fallbackFactory = Objects.requireNonNull(fallbackFactory, %22fallbackFactory%22)
 ;%0A  
@@ -2487,36 +2487,23 @@
 urn 
-CommandLine.default
+fallback
 Factory
-()
 .cre

add PicocliSpringFactory constructor that takes a specified fallback IFactory