Repository: quarkusio/quarkus
Issue: MP config injection types

According to [1] Quarkus app should be able to inject config properties like:

```java
@Inject
@ConfigProperty(name="myprj.some.dynamic.timeout", defaultValue="100")
private javax.inject.Provider<Long> timeout;
```

or

```java
@Inject @ConfigProperty(name="myPets") private List<String> myListPets;
```

The Provider injection fails with Arc as it cannot resolve injection [2] and second List injection fails because List converter is not used by default which I think it should be according to the spec [3]. It doesn't also work with Set or String[].

[1] https://github.com/eclipse/microprofile-config/blob/master/spec/src/main/asciidoc/configexamples.asciidoc#simple-dependency-injection-example
[2] https://github.com/xstefank/reproducers/tree/master/config-provided-prop
[3] https://github.com/xstefank/reproducers/tree/master/config-list-inject



Changed files:
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java
independent-projects/arc/runtime/src/main/java/io/quarkus/arc/CurrentInjectionPointProvider.java
independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceProvider.java
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java
independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/metadata/InjectionPointMetadataTest.java
independent-projects/arc/runtime/src/main/java/io/quarkus/arc/BeanManagerImpl.java
independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java

diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java
index fc7de49937b..b6e70710950 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java
@@ -1437,36 +1437,31 @@ protected void implementGetName(BeanInfo bean, ClassCreator beanCreator) {
 
     private ResultHandle wrapCurrentInjectionPoint(ClassOutput classOutput, ClassCreator beanCreator, BeanInfo bean,
             MethodCreator constructor, InjectionPointInfo injectionPoint, int paramIdx) {
-        // Collect qualifiers
-        ResultHandle requiredQualifiersHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
-        for (AnnotationInstance qualifierAnnotation : injectionPoint.getRequiredQualifiers()) {
-            BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
-            if (qualifier != null) {
-                constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, requiredQualifiersHandle,
-                        qualifier.getLiteralInstance(constructor));
-            } else {
-                // Create annotation literal if needed
-                ClassInfo qualifierClass = bean.getDeployment().getQualifier(qualifierAnnotation.name());
-                constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, requiredQualifiersHandle,
-                        annotationLiterals.process(constructor,
-                                classOutput, qualifierClass, qualifierAnnotation,
-                                Types.getPackageName(beanCreator.getClassName())));
-            }
-        }
-        // Collect all annotations
-        ResultHandle annotationsHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
+        ResultHandle requiredQualifiersHandle = collectQualifiers(classOutput, beanCreator, bean.getDeployment(), constructor,
+                injectionPoint,
+                annotationLiterals);
+        ResultHandle annotationsHandle = collectAnnotations(classOutput, beanCreator, bean.getDeployment(), constructor,
+                injectionPoint, annotationLiterals);
+        ResultHandle javaMemberHandle = getJavaMemberHandle(constructor, injectionPoint);
+        return constructor.newInstance(
+                MethodDescriptor.ofConstructor(CurrentInjectionPointProvider.class, InjectableBean.class,
+                        InjectableReferenceProvider.class, java.lang.reflect.Type.class,
+                        Set.class, Set.class, Member.class, int.class),
+                constructor.getThis(), constructor.getMethodParam(paramIdx),
+                Types.getTypeHandle(constructor, injectionPoint.getRequiredType()),
+                requiredQualifiersHandle, annotationsHandle, javaMemberHandle, constructor.load(injectionPoint.getPosition()));
+    }
+
+    static ResultHandle getJavaMemberHandle(MethodCreator constructor,
+            InjectionPointInfo injectionPoint) {
         ResultHandle javaMemberHandle;
-        Collection<AnnotationInstance> annotations;
         if (Kind.FIELD.equals(injectionPoint.getTarget().kind())) {
             FieldInfo field = injectionPoint.getTarget().asField();
-            annotations = bean.getDeployment().getAnnotations(field);
             javaMemberHandle = constructor.invokeStaticMethod(MethodDescriptors.REFLECTIONS_FIND_FIELD,
                     constructor.loadClass(field.declaringClass().name().toString()),
                     constructor.load(field.name()));
         } else {
             MethodInfo method = injectionPoint.getTarget().asMethod();
-            annotations = InjectionPointInfo.getParameterAnnotations(bean.getDeployment(),
-                    method, injectionPoint.getPosition());
             if (method.name().equals(Methods.INIT)) {
                 // Reflections.findConstructor(org.foo.SimpleBean.class,java.lang.String.class)                
                 ResultHandle[] paramsHandles = new ResultHandle[2];
@@ -1493,26 +1488,57 @@ private ResultHandle wrapCurrentInjectionPoint(ClassOutput classOutput, ClassCre
                 javaMemberHandle = constructor.invokeStaticMethod(MethodDescriptors.REFLECTIONS_FIND_METHOD, paramsHandles);
             }
         }
+        return javaMemberHandle;
+    }
+
+    static ResultHandle collectAnnotations(ClassOutput classOutput, ClassCreator beanCreator, BeanDeployment beanDeployment,
+            MethodCreator constructor,
+            InjectionPointInfo injectionPoint, AnnotationLiteralProcessor annotationLiterals) {
+        ResultHandle annotationsHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
+        Collection<AnnotationInstance> annotations;
+        if (Kind.FIELD.equals(injectionPoint.getTarget().kind())) {
+            FieldInfo field = injectionPoint.getTarget().asField();
+            annotations = beanDeployment.getAnnotations(field);
+        } else {
+            MethodInfo method = injectionPoint.getTarget().asMethod();
+            annotations = InjectionPointInfo.getParameterAnnotations(beanDeployment,
+                    method, injectionPoint.getPosition());
+        }
         for (AnnotationInstance annotation : annotations) {
             if (DotNames.INJECT.equals(annotation.name())) {
                 constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, annotationsHandle,
                         constructor.readStaticField(FieldDescriptor.of(InjectLiteral.class, "INSTANCE", InjectLiteral.class)));
             } else {
                 // Create annotation literal if needed
-                ClassInfo literalClass = bean.getDeployment().getIndex().getClassByName(annotation.name());
+                ClassInfo literalClass = beanDeployment.getIndex().getClassByName(annotation.name());
                 constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, annotationsHandle,
                         annotationLiterals.process(constructor,
                                 classOutput, literalClass, annotation,
                                 Types.getPackageName(beanCreator.getClassName())));
             }
         }
-        return constructor.newInstance(
-                MethodDescriptor.ofConstructor(CurrentInjectionPointProvider.class, InjectableBean.class,
-                        InjectableReferenceProvider.class, java.lang.reflect.Type.class,
-                        Set.class, Set.class, Member.class, int.class),
-                constructor.getThis(), constructor.getMethodParam(paramIdx),
-                Types.getTypeHandle(constructor, injectionPoint.getRequiredType()),
-                requiredQualifiersHandle, annotationsHandle, javaMemberHandle, constructor.load(injectionPoint.getPosition()));
+        return annotationsHandle;
+    }
+
+    static ResultHandle collectQualifiers(ClassOutput classOutput, ClassCreator beanCreator, BeanDeployment beanDeployment,
+            MethodCreator constructor,
+            InjectionPointInfo injectionPoint, AnnotationLiteralProcessor annotationLiterals) {
+        ResultHandle requiredQualifiersHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
+        for (AnnotationInstance qualifierAnnotation : injectionPoint.getRequiredQualifiers()) {
+            BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
+            if (qualifier != null) {
+                constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, requiredQualifiersHandle,
+                        qualifier.getLiteralInstance(constructor));
+            } else {
+                // Create annotation literal if needed
+                ClassInfo qualifierClass = beanDeployment.getQualifier(qualifierAnnotation.name());
+                constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, requiredQualifiersHandle,
+                        annotationLiterals.process(constructor,
+                                classOutput, qualifierClass, qualifierAnnotation,
+                                Types.getPackageName(beanCreator.getClassName())));
+            }
+        }
+        return requiredQualifiersHandle;
     }
 
 }
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
index 6b575c2bbe7..e6b48f29cc3 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
@@ -19,6 +19,7 @@
 import io.quarkus.arc.BeanManagerProvider;
 import io.quarkus.arc.BeanMetadataProvider;
 import io.quarkus.arc.EventProvider;
+import io.quarkus.arc.InjectableBean;
 import io.quarkus.arc.InjectableReferenceProvider;
 import io.quarkus.arc.InjectionPointProvider;
 import io.quarkus.arc.InstanceProvider;
@@ -30,6 +31,7 @@
 import io.quarkus.gizmo.MethodCreator;
 import io.quarkus.gizmo.MethodDescriptor;
 import io.quarkus.gizmo.ResultHandle;
+import java.lang.reflect.Member;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Predicate;
@@ -49,137 +51,125 @@ void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionP
                 ClassCreator clazzCreator,
                 MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
 
-            ResultHandle qualifiers = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
-            if (!injectionPoint.getRequiredQualifiers().isEmpty()) {
-                // Set<Annotation> instanceProvider1Qualifiers = new HashSet<>()
-                // instanceProvider1Qualifiers.add(javax.enterprise.inject.Default.Literal.INSTANCE)
-
-                for (AnnotationInstance qualifierAnnotation : injectionPoint.getRequiredQualifiers()) {
-                    BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
-                    if (qualifier != null) {
-                        constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
-                                qualifier.getLiteralInstance(constructor));
-                    } else {
-                        // Create annotation literal first
-                        ClassInfo qualifierClass = beanDeployment.getQualifier(qualifierAnnotation.name());
-                        constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
-                                annotationLiterals.process(constructor, classOutput,
-                                        qualifierClass, qualifierAnnotation,
-                                        Types.getPackageName(clazzCreator.getClassName())));
-                    }
-                }
-            }
+            ResultHandle qualifiers = BeanGenerator.collectQualifiers(classOutput, clazzCreator, beanDeployment, constructor,
+                    injectionPoint,
+                    annotationLiterals);
             ResultHandle parameterizedType = Types.getTypeHandle(constructor, injectionPoint.getRequiredType());
+            ResultHandle annotationsHandle = BeanGenerator.collectAnnotations(classOutput, clazzCreator, beanDeployment,
+                    constructor,
+                    injectionPoint, annotationLiterals);
+            ResultHandle javaMemberHandle = BeanGenerator.getJavaMemberHandle(constructor, injectionPoint);
             ResultHandle instanceProvider = constructor.newInstance(
-                    MethodDescriptor.ofConstructor(InstanceProvider.class, java.lang.reflect.Type.class, Set.class),
-                    parameterizedType, qualifiers);
+                    MethodDescriptor.ofConstructor(InstanceProvider.class, java.lang.reflect.Type.class, Set.class,
+                            InjectableBean.class, Set.class, Member.class, int.class),
+                    parameterizedType, qualifiers, constructor.getThis(), annotationsHandle, javaMemberHandle,
+                    constructor.load(injectionPoint.getPosition()));
             constructor.writeInstanceField(
                     FieldDescriptor.of(clazzCreator.getClassName(), providerName, InjectableReferenceProvider.class.getName()),
                     constructor.getThis(), instanceProvider);
 
         }
-    }, ip -> ip.getKind() == InjectionPointKind.CDI && (DotNames.INSTANCE.equals(ip.getRequiredType().name())
-            || DotNames.PROVIDER.equals(ip.getRequiredType().name()))), INJECTION_POINT(DotNames.INJECTION_POINT,
-                    new Generator() {
-                        @Override
-                        void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
-                                ClassCreator clazzCreator,
-                                MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
-                            // this.injectionPointProvider1 = new InjectionPointProvider();
-                            constructor.writeInstanceField(
-                                    FieldDescriptor.of(clazzCreator.getClassName(), providerName,
-                                            InjectableReferenceProvider.class.getName()),
-                                    constructor.getThis(),
-                                    constructor.newInstance(MethodDescriptor.ofConstructor(InjectionPointProvider.class)));
-                        }
-                    }), BEAN(DotNames.BEAN, new Generator() {
-                        @Override
-                        void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
-                                ClassCreator clazzCreator,
-                                MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
-                            // this.beanProvider1 = new BeanMetadataProvider<>();
-                            constructor.writeInstanceField(
-                                    FieldDescriptor.of(clazzCreator.getClassName(), providerName,
-                                            InjectableReferenceProvider.class.getName()),
-                                    constructor.getThis(),
-                                    constructor.newInstance(MethodDescriptor.ofConstructor(BeanMetadataProvider.class)));
-                        }
-                    }), BEAN_MANAGER(DotNames.BEAN_MANAGER, new Generator() {
-                        @Override
-                        void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
-                                ClassCreator clazzCreator,
-                                MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
-                            constructor.writeInstanceField(
-                                    FieldDescriptor.of(clazzCreator.getClassName(), providerName,
-                                            InjectableReferenceProvider.class.getName()),
-                                    constructor.getThis(),
-                                    constructor.newInstance(MethodDescriptor.ofConstructor(BeanManagerProvider.class)));
-                        }
-                    }), EVENT(DotNames.EVENT, new Generator() {
-                        @Override
-                        void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
-                                ClassCreator clazzCreator,
-                                MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
-
-                            ResultHandle qualifiers = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
-                            if (!injectionPoint.getRequiredQualifiers().isEmpty()) {
-                                // Set<Annotation> instanceProvider1Qualifiers = new HashSet<>()
-                                // instanceProvider1Qualifiers.add(javax.enterprise.inject.Default.Literal.INSTANCE)
-
-                                for (AnnotationInstance qualifierAnnotation : injectionPoint.getRequiredQualifiers()) {
-                                    BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
-                                    if (qualifier != null) {
-                                        constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
-                                                qualifier.getLiteralInstance(constructor));
-                                    } else {
-                                        // Create annotation literal first
-                                        ClassInfo qualifierClass = beanDeployment.getQualifier(qualifierAnnotation.name());
-                                        constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
-                                                annotationLiterals.process(constructor, classOutput,
-                                                        qualifierClass, qualifierAnnotation,
-                                                        Types.getPackageName(clazzCreator.getClassName())));
-                                    }
-                                }
+    }, BuiltinBean::isInstanceInjectionPoint), INJECTION_POINT(DotNames.INJECTION_POINT,
+            new Generator() {
+                @Override
+                void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
+                        ClassCreator clazzCreator,
+                        MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
+                    // this.injectionPointProvider1 = new InjectionPointProvider();
+                    constructor.writeInstanceField(
+                            FieldDescriptor.of(clazzCreator.getClassName(), providerName,
+                                    InjectableReferenceProvider.class.getName()),
+                            constructor.getThis(),
+                            constructor.newInstance(MethodDescriptor.ofConstructor(InjectionPointProvider.class)));
+                }
+            }), BEAN(DotNames.BEAN, new Generator() {
+                @Override
+                void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
+                        ClassCreator clazzCreator,
+                        MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
+                    // this.beanProvider1 = new BeanMetadataProvider<>();
+                    constructor.writeInstanceField(
+                            FieldDescriptor.of(clazzCreator.getClassName(), providerName,
+                                    InjectableReferenceProvider.class.getName()),
+                            constructor.getThis(),
+                            constructor.newInstance(MethodDescriptor.ofConstructor(BeanMetadataProvider.class)));
+                }
+            }), BEAN_MANAGER(DotNames.BEAN_MANAGER, new Generator() {
+                @Override
+                void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
+                        ClassCreator clazzCreator,
+                        MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
+                    constructor.writeInstanceField(
+                            FieldDescriptor.of(clazzCreator.getClassName(), providerName,
+                                    InjectableReferenceProvider.class.getName()),
+                            constructor.getThis(),
+                            constructor.newInstance(MethodDescriptor.ofConstructor(BeanManagerProvider.class)));
+                }
+            }), EVENT(DotNames.EVENT, new Generator() {
+                @Override
+                void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
+                        ClassCreator clazzCreator,
+                        MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
+
+                    ResultHandle qualifiers = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
+                    if (!injectionPoint.getRequiredQualifiers().isEmpty()) {
+                        // Set<Annotation> instanceProvider1Qualifiers = new HashSet<>()
+                        // instanceProvider1Qualifiers.add(javax.enterprise.inject.Default.Literal.INSTANCE)
+
+                        for (AnnotationInstance qualifierAnnotation : injectionPoint.getRequiredQualifiers()) {
+                            BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
+                            if (qualifier != null) {
+                                constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
+                                        qualifier.getLiteralInstance(constructor));
+                            } else {
+                                // Create annotation literal first
+                                ClassInfo qualifierClass = beanDeployment.getQualifier(qualifierAnnotation.name());
+                                constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
+                                        annotationLiterals.process(constructor, classOutput,
+                                                qualifierClass, qualifierAnnotation,
+                                                Types.getPackageName(clazzCreator.getClassName())));
                             }
-                            ResultHandle parameterizedType = Types.getTypeHandle(constructor, injectionPoint.getRequiredType());
-                            ResultHandle eventProvider = constructor.newInstance(
-                                    MethodDescriptor.ofConstructor(EventProvider.class, java.lang.reflect.Type.class,
-                                            Set.class),
-                                    parameterizedType, qualifiers);
-                            constructor.writeInstanceField(
-                                    FieldDescriptor.of(clazzCreator.getClassName(), providerName,
-                                            InjectableReferenceProvider.class.getName()),
-                                    constructor.getThis(), eventProvider);
                         }
-                    }), RESOURCE(DotNames.OBJECT, new Generator() {
-                        @Override
-                        void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
-                                ClassCreator clazzCreator,
-                                MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
-
-                            ResultHandle annotations = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
-                            // For a resource field the required qualifiers contain all annotations declared on the field
-                            if (!injectionPoint.getRequiredQualifiers().isEmpty()) {
-                                for (AnnotationInstance annotation : injectionPoint.getRequiredQualifiers()) {
-                                    // Create annotation literal first
-                                    ClassInfo annotationClass = beanDeployment.getIndex().getClassByName(annotation.name());
-                                    constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, annotations,
-                                            annotationLiterals.process(constructor, classOutput,
-                                                    annotationClass, annotation,
-                                                    Types.getPackageName(clazzCreator.getClassName())));
-                                }
-                            }
-                            ResultHandle parameterizedType = Types.getTypeHandle(constructor, injectionPoint.getRequiredType());
-                            ResultHandle resourceProvider = constructor.newInstance(
-                                    MethodDescriptor.ofConstructor(ResourceProvider.class, java.lang.reflect.Type.class,
-                                            Set.class),
-                                    parameterizedType, annotations);
-                            constructor.writeInstanceField(
-                                    FieldDescriptor.of(clazzCreator.getClassName(), providerName,
-                                            InjectableReferenceProvider.class.getName()),
-                                    constructor.getThis(), resourceProvider);
+                    }
+                    ResultHandle parameterizedType = Types.getTypeHandle(constructor, injectionPoint.getRequiredType());
+                    ResultHandle eventProvider = constructor.newInstance(
+                            MethodDescriptor.ofConstructor(EventProvider.class, java.lang.reflect.Type.class,
+                                    Set.class),
+                            parameterizedType, qualifiers);
+                    constructor.writeInstanceField(
+                            FieldDescriptor.of(clazzCreator.getClassName(), providerName,
+                                    InjectableReferenceProvider.class.getName()),
+                            constructor.getThis(), eventProvider);
+                }
+            }), RESOURCE(DotNames.OBJECT, new Generator() {
+                @Override
+                void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint,
+                        ClassCreator clazzCreator,
+                        MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
+
+                    ResultHandle annotations = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
+                    // For a resource field the required qualifiers contain all annotations declared on the field
+                    if (!injectionPoint.getRequiredQualifiers().isEmpty()) {
+                        for (AnnotationInstance annotation : injectionPoint.getRequiredQualifiers()) {
+                            // Create annotation literal first
+                            ClassInfo annotationClass = beanDeployment.getIndex().getClassByName(annotation.name());
+                            constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, annotations,
+                                    annotationLiterals.process(constructor, classOutput,
+                                            annotationClass, annotation,
+                                            Types.getPackageName(clazzCreator.getClassName())));
                         }
-                    }, ip -> ip.getKind() == InjectionPointKind.RESOURCE);
+                    }
+                    ResultHandle parameterizedType = Types.getTypeHandle(constructor, injectionPoint.getRequiredType());
+                    ResultHandle resourceProvider = constructor.newInstance(
+                            MethodDescriptor.ofConstructor(ResourceProvider.class, java.lang.reflect.Type.class,
+                                    Set.class),
+                            parameterizedType, annotations);
+                    constructor.writeInstanceField(
+                            FieldDescriptor.of(clazzCreator.getClassName(), providerName,
+                                    InjectableReferenceProvider.class.getName()),
+                            constructor.getThis(), resourceProvider);
+                }
+            }, ip -> ip.getKind() == InjectionPointKind.RESOURCE);
 
     private final DotName rawTypeDotName;
 
@@ -188,8 +178,7 @@ void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionP
     private final Predicate<InjectionPointInfo> matcher;
 
     BuiltinBean(DotName rawTypeDotName, Generator generator) {
-        this(rawTypeDotName, generator,
-                ip -> ip.getKind() == InjectionPointKind.CDI && rawTypeDotName.equals(ip.getRequiredType().name()));
+        this(rawTypeDotName, generator, ip -> isCdiAndRawTypeMatches(ip, rawTypeDotName));
     }
 
     BuiltinBean(DotName rawTypeDotName, Generator generator, Predicate<InjectionPointInfo> matcher) {
@@ -231,4 +220,19 @@ abstract void generate(ClassOutput classOutput, BeanDeployment beanDeployment, I
 
     }
 
+    private static boolean isCdiAndRawTypeMatches(InjectionPointInfo injectionPoint, DotName rawTypeDotName) {
+        if (injectionPoint.getKind() != InjectionPointKind.CDI) {
+            return false;
+        }
+        return rawTypeDotName.equals(injectionPoint.getRequiredType().name());
+    }
+
+    private static boolean isInstanceInjectionPoint(InjectionPointInfo injectionPoint) {
+        if (injectionPoint.getKind() != InjectionPointKind.CDI) {
+            return false;
+        }
+        return DotNames.INSTANCE.equals(injectionPoint.getRequiredType().name())
+                || DotNames.PROVIDER.equals(injectionPoint.getRequiredType().name());
+    }
+
 }
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java
index e223e1f3db8..5720628ea47 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java
@@ -35,6 +35,7 @@
 import io.quarkus.gizmo.MethodCreator;
 import io.quarkus.gizmo.MethodDescriptor;
 import io.quarkus.gizmo.ResultHandle;
+import java.lang.reflect.Member;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -306,29 +307,23 @@ protected void createConstructor(ClassOutput classOutput, ClassCreator observerC
                         .anyMatch(ip -> BuiltinBean.INJECTION_POINT.getRawTypeDotName().equals(ip.getRequiredType().name()))) {
                     // IMPL NOTE: Injection point resolves to a dependent bean that injects InjectionPoint metadata and so we need to wrap the injectable
                     // reference provider
-                    ResultHandle requiredQualifiersHandle = constructor
-                            .newInstance(MethodDescriptor.ofConstructor(HashSet.class));
-                    for (AnnotationInstance qualifierAnnotation : injectionPoint.getRequiredQualifiers()) {
-                        BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
-                        if (qualifier != null) {
-                            constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, requiredQualifiersHandle,
-                                    qualifier.getLiteralInstance(constructor));
-                        } else {
-                            // Create annotation literal first
-                            ClassInfo qualifierClass = observer.getDeclaringBean().getDeployment()
-                                    .getQualifier(qualifierAnnotation.name());
-                            constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, requiredQualifiersHandle,
-                                    annotationLiterals.process(constructor,
-                                            classOutput, qualifierClass, qualifierAnnotation,
-                                            Types.getPackageName(observerCreator.getClassName())));
-                        }
-                    }
+                    ResultHandle requiredQualifiersHandle = BeanGenerator.collectQualifiers(classOutput, observerCreator,
+                            observer.getDeclaringBean().getDeployment(), constructor,
+                            injectionPoint,
+                            annotationLiterals);
+                    ResultHandle annotationsHandle = BeanGenerator.collectAnnotations(classOutput, observerCreator,
+                            observer.getDeclaringBean().getDeployment(), constructor,
+                            injectionPoint, annotationLiterals);
+                    ResultHandle javaMemberHandle = BeanGenerator.getJavaMemberHandle(constructor, injectionPoint);
                     ResultHandle wrapHandle = constructor.newInstance(
-                            MethodDescriptor.ofConstructor(CurrentInjectionPointProvider.class,
+                            MethodDescriptor.ofConstructor(CurrentInjectionPointProvider.class, InjectableBean.class,
                                     InjectableReferenceProvider.class, java.lang.reflect.Type.class,
-                                    Set.class),
-                            constructor.getMethodParam(paramIdx++),
-                            Types.getTypeHandle(constructor, injectionPoint.getRequiredType()), requiredQualifiersHandle);
+                                    Set.class, Set.class, Member.class, int.class),
+                            constructor.getThis(), constructor.getMethodParam(paramIdx++),
+                            Types.getTypeHandle(constructor, injectionPoint.getRequiredType()),
+                            requiredQualifiersHandle, annotationsHandle, javaMemberHandle,
+                            constructor.load(injectionPoint.getPosition()));
+
                     constructor.writeInstanceField(FieldDescriptor.of(observerCreator.getClassName(),
                             injectionPointToProviderField.get(injectionPoint),
                             InjectableReferenceProvider.class.getName()), constructor.getThis(), wrapHandle);
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/BeanManagerImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/BeanManagerImpl.java
index 0098db3f8a0..14f0430f42e 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/BeanManagerImpl.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/BeanManagerImpl.java
@@ -18,6 +18,7 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
@@ -48,6 +49,7 @@
 import javax.enterprise.inject.spi.Interceptor;
 import javax.enterprise.inject.spi.ObserverMethod;
 import javax.enterprise.inject.spi.ProducerFactory;
+import javax.enterprise.util.TypeLiteral;
 import javax.interceptor.InterceptorBinding;
 
 /**
@@ -55,6 +57,10 @@
  */
 public class BeanManagerImpl implements BeanManager {
 
+    @SuppressWarnings("serial")
+    static final TypeLiteral<Instance<Object>> INSTANCE_LITERAL = new TypeLiteral<Instance<Object>>() {
+    };
+
     static final LazyValue<BeanManagerImpl> INSTANCE = new LazyValue<>(BeanManagerImpl::new);
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -279,7 +285,8 @@ public Event<Object> getEvent() {
 
     @Override
     public Instance<Object> createInstance() {
-        return new InstanceImpl<>(Object.class, null, new CreationalContextImpl<>());
+        return new InstanceImpl<>(null, INSTANCE_LITERAL.getType(), Collections.emptySet(), new CreationalContextImpl<>(),
+                Collections.emptySet(), null, -1);
     }
 
 }
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/CurrentInjectionPointProvider.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/CurrentInjectionPointProvider.java
index 7859d7739e7..d310eb7d4a9 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/CurrentInjectionPointProvider.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/CurrentInjectionPointProvider.java
@@ -45,7 +45,8 @@
  */
 public class CurrentInjectionPointProvider<T> implements InjectableReferenceProvider<T> {
 
-    static final InjectionPoint EMPTY = new InjectionPointImpl(Object.class, Collections.emptySet(), null, null, null, -1);
+    static final InjectionPoint EMPTY = new InjectionPointImpl(Object.class, Object.class, Collections.emptySet(), null, null,
+            null, -1);
 
     private final InjectableReferenceProvider<T> delegate;
 
@@ -54,7 +55,8 @@
     public CurrentInjectionPointProvider(InjectableBean<?> bean, InjectableReferenceProvider<T> delegate, Type requiredType,
             Set<Annotation> qualifiers, Set<Annotation> annotations, Member javaMember, int position) {
         this.delegate = delegate;
-        this.injectionPoint = new InjectionPointImpl(requiredType, qualifiers, bean, annotations, javaMember, position);
+        this.injectionPoint = new InjectionPointImpl(requiredType, requiredType, qualifiers, bean, annotations, javaMember,
+                position);
     }
 
     @Override
@@ -72,7 +74,7 @@ public T get(CreationalContext<T> creationalContext) {
         }
     }
 
-    private static class InjectionPointImpl implements InjectionPoint {
+    static class InjectionPointImpl implements InjectionPoint {
 
         private final Type requiredType;
         private final Set<Annotation> qualifiers;
@@ -80,15 +82,17 @@ private static class InjectionPointImpl implements InjectionPoint {
         private final Annotated annotated;
         private final Member member;
 
-        InjectionPointImpl(Type requiredType, Set<Annotation> qualifiers, InjectableBean<?> bean, Set<Annotation> annotations,
+        InjectionPointImpl(Type injectionPointType, Type requiredType, Set<Annotation> qualifiers, InjectableBean<?> bean,
+                Set<Annotation> annotations,
                 Member javaMember, int position) {
             this.requiredType = requiredType;
             this.qualifiers = qualifiers;
             this.bean = bean;
             if (javaMember instanceof Executable) {
-                this.annotated = new AnnotatedParameterImpl<>(requiredType, annotations, position, (Executable) javaMember);
+                this.annotated = new AnnotatedParameterImpl<>(injectionPointType, annotations, position,
+                        (Executable) javaMember);
             } else {
-                this.annotated = new AnnotatedFieldImpl<>(requiredType, annotations, (Field) javaMember);
+                this.annotated = new AnnotatedFieldImpl<>(injectionPointType, annotations, (Field) javaMember);
             }
             this.member = javaMember;
         }
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java
index 779fbed4a69..2c51f5fc039 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java
@@ -16,7 +16,9 @@
 
 package io.quarkus.arc;
 
+import io.quarkus.arc.CurrentInjectionPointProvider.InjectionPointImpl;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Collection;
@@ -27,6 +29,7 @@
 import javax.enterprise.inject.AmbiguousResolutionException;
 import javax.enterprise.inject.Instance;
 import javax.enterprise.inject.UnsatisfiedResolutionException;
+import javax.enterprise.inject.spi.InjectionPoint;
 import javax.enterprise.util.TypeLiteral;
 import javax.inject.Provider;
 
@@ -38,34 +41,43 @@
 
     private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[] {};
 
-    private final Type type;
-
-    private final Set<Annotation> qualifiers;
-
     private final CreationalContextImpl<?> creationalContext;
+    private final Set<InjectableBean<?>> resolvedBeans;
+
+    private final Type injectionPointType;
+    private final Type requiredType;
+    private final Set<Annotation> requiredQualifiers;
+    private final InjectableBean<?> targetBean;
+    private final Set<Annotation> annotations;
+    private final Member javaMember;
+    private final int position;
+
+    InstanceImpl(InjectableBean<?> targetBean, Type type, Set<Annotation> qualifiers,
+            CreationalContextImpl<?> creationalContext, Set<Annotation> annotations, Member javaMember, int position) {
+        this(targetBean, type, getRequiredType(type), qualifiers, creationalContext, annotations, javaMember, position);
+    }
 
-    private final Set<InjectableBean<?>> beans;
+    InstanceImpl(InstanceImpl<?> parent, Type requiredType, Set<Annotation> requiredQualifiers) {
+        this(parent.targetBean, parent.injectionPointType, requiredType, requiredQualifiers, parent.creationalContext,
+                parent.annotations, parent.javaMember, parent.position);
+    }
 
-    InstanceImpl(Type type, Set<Annotation> qualifiers, CreationalContextImpl<?> creationalContext) {
-        if (type instanceof ParameterizedType) {
-            ParameterizedType parameterizedType = (ParameterizedType) type;
-            if (Provider.class.isAssignableFrom(Types.getRawType(parameterizedType.getRawType()))) {
-                this.type = parameterizedType.getActualTypeArguments()[0];
-            } else {
-                this.type = type;
-            }
-        } else {
-            this.type = type;
-        }
-        this.qualifiers = qualifiers != null ? qualifiers : Collections.emptySet();
+    InstanceImpl(InjectableBean<?> targetBean, Type injectionPointType, Type requiredType, Set<Annotation> requiredQualifiers,
+            CreationalContextImpl<?> creationalContext, Set<Annotation> annotations, Member javaMember, int position) {
+        this.injectionPointType = injectionPointType;
+        this.requiredType = requiredType;
+        this.requiredQualifiers = requiredQualifiers != null ? requiredQualifiers : Collections.emptySet();
         this.creationalContext = creationalContext;
-
-        if (this.qualifiers.isEmpty() && Object.class.equals(type)) {
+        if (this.requiredQualifiers.isEmpty() && Object.class.equals(requiredType)) {
             // Do not prefetch the beans for Instance<Object> with no qualifiers
-            this.beans = null;
+            this.resolvedBeans = null;
         } else {
-            this.beans = resolve();
+            this.resolvedBeans = resolve();
         }
+        this.targetBean = targetBean;
+        this.annotations = annotations;
+        this.javaMember = javaMember;
+        this.position = position;
     }
 
     @Override
@@ -87,23 +99,23 @@ public T get() {
 
     @Override
     public Instance<T> select(Annotation... qualifiers) {
-        Set<Annotation> newQualifiers = new HashSet<>(this.qualifiers);
+        Set<Annotation> newQualifiers = new HashSet<>(this.requiredQualifiers);
         Collections.addAll(newQualifiers, qualifiers);
-        return new InstanceImpl<>(type, newQualifiers, creationalContext);
+        return new InstanceImpl<>(this, requiredType, newQualifiers);
     }
 
     @Override
     public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifiers) {
-        Set<Annotation> newQualifiers = new HashSet<>(this.qualifiers);
+        Set<Annotation> newQualifiers = new HashSet<>(this.requiredQualifiers);
         Collections.addAll(newQualifiers, qualifiers);
-        return new InstanceImpl<>(subtype, newQualifiers, creationalContext);
+        return new InstanceImpl<>(this, subtype, newQualifiers);
     }
 
     @Override
     public <U extends T> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
-        Set<Annotation> newQualifiers = new HashSet<>(this.qualifiers);
+        Set<Annotation> newQualifiers = new HashSet<>(this.requiredQualifiers);
         Collections.addAll(newQualifiers, qualifiers);
-        return new InstanceImpl<>(subtype.getType(), newQualifiers, creationalContext);
+        return new InstanceImpl<>(this, subtype.getType(), newQualifiers);
     }
 
     @Override
@@ -131,17 +143,29 @@ void destroy() {
 
     private T getBeanInstance(InjectableBean<T> bean) {
         CreationalContextImpl<T> ctx = creationalContext.child();
-        // TODO current injection point?
-        T instance = bean.get(ctx);
+        InjectionPoint prev = InjectionPointProvider.CURRENT.get();
+        InjectionPointProvider.CURRENT
+                .set(new InjectionPointImpl(injectionPointType, requiredType, requiredQualifiers, targetBean, annotations,
+                        javaMember, position));
+        T instance;
+        try {
+            instance = bean.get(ctx);
+        } finally {
+            if (prev != null) {
+                InjectionPointProvider.CURRENT.set(prev);
+            } else {
+                InjectionPointProvider.CURRENT.remove();
+            }
+        }
         return instance;
     }
 
     private Set<InjectableBean<?>> beans() {
-        return beans != null ? beans : resolve();
+        return resolvedBeans != null ? resolvedBeans : resolve();
     }
 
     private Set<InjectableBean<?>> resolve() {
-        return ArcContainerImpl.instance().getResolvedBeans(type, qualifiers.toArray(EMPTY_ANNOTATION_ARRAY));
+        return ArcContainerImpl.instance().getResolvedBeans(requiredType, requiredQualifiers.toArray(EMPTY_ANNOTATION_ARRAY));
     }
 
     class InstanceIterator implements Iterator<T> {
@@ -170,4 +194,14 @@ public T next() {
 
     }
 
+    private static Type getRequiredType(Type type) {
+        if (type instanceof ParameterizedType) {
+            ParameterizedType parameterizedType = (ParameterizedType) type;
+            if (Provider.class.isAssignableFrom(Types.getRawType(parameterizedType.getRawType()))) {
+                return parameterizedType.getActualTypeArguments()[0];
+            }
+        }
+        throw new IllegalArgumentException("Not a valid type: " + type);
+    }
+
 }
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceProvider.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceProvider.java
index 7a6fe1a8bcd..6605ccaa0bc 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceProvider.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceProvider.java
@@ -17,6 +17,7 @@
 package io.quarkus.arc;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
 import java.lang.reflect.Type;
 import java.util.Set;
 import javax.enterprise.context.spi.CreationalContext;
@@ -29,17 +30,26 @@
 public class InstanceProvider<T> implements InjectableReferenceProvider<Instance<T>> {
 
     private final Type requiredType;
-
     private final Set<Annotation> qualifiers;
+    private final InjectableBean<?> targetBean;
+    private final Set<Annotation> annotations;
+    private final Member javaMember;
+    private final int position;
 
-    public InstanceProvider(Type type, Set<Annotation> qualifiers) {
+    public InstanceProvider(Type type, Set<Annotation> qualifiers, InjectableBean<?> targetBean, Set<Annotation> annotations,
+            Member javaMember, int position) {
         this.requiredType = type;
         this.qualifiers = qualifiers;
+        this.targetBean = targetBean;
+        this.annotations = annotations;
+        this.javaMember = javaMember;
+        this.position = position;
     }
 
     @Override
     public Instance<T> get(CreationalContext<Instance<T>> creationalContext) {
-        return new InstanceImpl<T>(requiredType, qualifiers, CreationalContextImpl.unwrap(creationalContext));
+        return new InstanceImpl<T>(targetBean, requiredType, qualifiers, CreationalContextImpl.unwrap(creationalContext),
+                annotations, javaMember, position);
     }
 
 }
diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/metadata/InjectionPointMetadataTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/metadata/InjectionPointMetadataTest.java
index c935d56ea7e..ab60da7613e 100644
--- a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/metadata/InjectionPointMetadataTest.java
+++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/metadata/InjectionPointMetadataTest.java
@@ -27,12 +27,14 @@
 import java.util.Set;
 import javax.enterprise.context.Dependent;
 import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Instance;
 import javax.enterprise.inject.spi.AnnotatedConstructor;
 import javax.enterprise.inject.spi.AnnotatedField;
 import javax.enterprise.inject.spi.AnnotatedParameter;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.util.TypeLiteral;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.junit.Rule;
@@ -43,7 +45,7 @@ public class InjectionPointMetadataTest {
     @Rule
     public ArcTestContainer container = new ArcTestContainer(Controller.class, Controlled.class);
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({ "unchecked", "rawtypes", "serial" })
     @Test
     public void testInjectionPointMetadata() {
         ArcContainer arc = Arc.container();
@@ -83,7 +85,7 @@ public void testInjectionPointMetadata() {
         // Constructor
         InjectionPoint ctorInjectionPoint = controller.controlledCtor.injectionPoint;
         assertNotNull(ctorInjectionPoint);
-        assertEquals(Controlled.class, methodInjectionPoint.getType());
+        assertEquals(Controlled.class, ctorInjectionPoint.getType());
         assertTrue(ctorInjectionPoint.getAnnotated() instanceof AnnotatedParameter);
         assertEquals(bean, ctorInjectionPoint.getBean());
         AnnotatedParameter<Controller> ctorParam = (AnnotatedParameter<Controller>) ctorInjectionPoint.getAnnotated();
@@ -94,6 +96,27 @@ public void testInjectionPointMetadata() {
         assertEquals(1, ctorParam.getAnnotations().size());
         assertTrue(ctorParam.getDeclaringCallable() instanceof AnnotatedConstructor);
         assertEquals(Controller.class, ctorParam.getDeclaringCallable().getJavaMember().getDeclaringClass());
+
+        // Instance
+        InjectionPoint instanceInjectionPoint = controller.instanceControlled.get().injectionPoint;
+        assertNotNull(instanceInjectionPoint);
+        assertEquals(Controlled.class, instanceInjectionPoint.getType());
+        qualifiers = instanceInjectionPoint.getQualifiers();
+        assertEquals(1, qualifiers.size());
+        assertEquals(Default.class, qualifiers.iterator().next().annotationType());
+        bean = instanceInjectionPoint.getBean();
+        assertNotNull(bean);
+        assertTrue(bean.getTypes().stream().anyMatch(t -> t.equals(Controller.class)));
+        assertNotNull(instanceInjectionPoint.getAnnotated());
+        assertTrue(instanceInjectionPoint.getAnnotated() instanceof AnnotatedField);
+        annotatedField = (AnnotatedField) instanceInjectionPoint.getAnnotated();
+        assertEquals("instanceControlled", annotatedField.getJavaMember().getName());
+        assertEquals(new TypeLiteral<Instance<Controlled>>() {
+        }.getType(), annotatedField.getBaseType());
+        assertTrue(annotatedField.isAnnotationPresent(Inject.class));
+        assertTrue(annotatedField.getAnnotation(Singleton.class) == null);
+        assertTrue(annotatedField.getAnnotations(Singleton.class).isEmpty());
+        assertEquals(1, annotatedField.getAnnotations().size());
     }
 
     @Singleton
@@ -106,6 +129,9 @@ static class Controller {
 
         Controlled controlledCtor;
 
+        @Inject
+        Instance<Controlled> instanceControlled;
+
         @Inject
         public Controller(BeanManager beanManager, @Singleton Controlled controlled) {
             this.controlledCtor = controlled;