work in progress
diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
index d06787e..18c6b3e 100644
--- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
@@ -19,23 +19,8 @@
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
+import java.lang.reflect.*;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -495,6 +480,61 @@
         }
     }
 
+    @NotNull
+    private InjectableElement getElement(InjectableElement element, Type type) {
+        return new InjectableElement() {
+            @Override
+            public AnnotatedElement getAnnotatedElement() {
+                return element.getAnnotatedElement();
+            }
+
+            @Override
+            public Type getType() {
+                return type;
+            }
+
+            @Override
+            public boolean isPrimitive() {
+                return element.isPrimitive();
+            }
+
+            @Override
+            public String getName() {
+                return element.getName();
+            }
+
+            @Override
+            public String getSource() {
+                return element.getSource();
+            }
+
+            @Override
+            public String getVia() {
+                return element.getVia();
+            }
+
+            @Override
+            public Class<? extends ViaProviderType> getViaProviderType() {
+                return element.getViaProviderType();
+            }
+
+            @Override
+            public boolean hasDefaultValue() {
+                return true;
+            }
+
+            @Override
+            public Object getDefaultValue() {
+                return Optional.empty();
+            }
+
+            @Override
+            public boolean isOptional(InjectAnnotationProcessor annotationProcessor) {
+                return true;
+            }
+        };
+    }
+
     private
     @Nullable
     RuntimeException injectElement(final InjectableElement element, final Object adaptable,
@@ -502,6 +542,26 @@
                                    final @NotNull Map<ValuePreparer, Object> preparedValues,
                                    final @Nullable BundleContext modelContext) {
 
+        Type genericType = ((InjectableField) element).getFieldGenericType();
+
+        if (genericType instanceof ParameterizedType) {
+            ParameterizedType pType = (ParameterizedType) genericType;
+            if (pType.getRawType().equals(Optional.class)) {
+                InjectableElement el = getElement(element, pType.getActualTypeArguments()[0]);
+                return injectElementInternal(el, adaptable, registry, (element1, value)
+                        -> callback.inject(element, value != Optional.empty() ? Optional.ofNullable(value) : value), preparedValues, modelContext);
+            }
+        }
+        return injectElementInternal(element, adaptable, registry, callback, preparedValues, modelContext);
+    }
+
+    private
+    @Nullable
+    RuntimeException injectElementInternal(final InjectableElement element, final Object adaptable,
+                                   final @NotNull DisposalCallbackRegistry registry, final InjectCallback callback,
+                                   final @NotNull Map<ValuePreparer, Object> preparedValues,
+                                   final @Nullable BundleContext modelContext) {
+
         InjectAnnotationProcessor annotationProcessor = null;
         String source = element.getSource();
         boolean wasInjectionSuccessful = false;
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
index 92036f7..f24b367 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
@@ -23,7 +23,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import java.util.Optional;
 
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.ObjectUtils;
@@ -99,11 +98,6 @@
                 return null;
             }
             Class<?> collectionType = (Class<?>) pType.getRawType();
-
-            if (collectionType.equals(Optional.class)) {
-                return Optional.ofNullable(map.get(name));
-            }
-
             if (!(collectionType.equals(Collection.class) || collectionType.equals(List.class))) {
                 return null;
             }
diff --git a/src/test/java/org/apache/sling/models/impl/OptionalObjectsTest.java b/src/test/java/org/apache/sling/models/impl/OptionalObjectsTest.java
index 13a63b6..bd4f00d 100644
--- a/src/test/java/org/apache/sling/models/impl/OptionalObjectsTest.java
+++ b/src/test/java/org/apache/sling/models/impl/OptionalObjectsTest.java
@@ -19,7 +19,6 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Optional;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
@@ -29,7 +28,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.runners.MockitoJUnitRunner;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -60,51 +59,21 @@
         map.put("optionalChar", '1');
         map.put("optionalBoolean", Boolean.valueOf("true"));
         map.put("optionalList", Arrays.asList("foo", "bar", "baz"));
+        map.put("optional2List", Arrays.asList("foo1", "bar1", "baz1"));
         map.put("optionalArray", new String[]{"qux", "quux"});
 
         Resource res = mock(Resource.class);
         when(res.adaptTo(ValueMap.class)).thenReturn(new ValueMapDecorator(map));
 
+
         org.apache.sling.models.testmodels.classes.OptionalObjectsModel model = factory.getAdapter(res,
                 org.apache.sling.models.testmodels.classes.OptionalObjectsModel.class);
         assertNotNull(model);
 
-        assertEquals(Optional.of("foo bar baz"), model.getOptionalString());
-        assertEquals(Optional.empty(), model.getOptionalNullString());
-
-        assertEquals(Optional.of(1), model.getOptionalInteger());
-        assertEquals(Optional.empty(), model.getOptionalNullInteger());
-
-        assertEquals(Optional.of(Byte.valueOf("1")), model.getOptionalByte());
-        assertEquals(Optional.empty(), model.getOptionalNullByte());
-
-        assertEquals(Optional.of(Long.valueOf("1")), model.getOptionalLong());
-        assertEquals(Optional.empty(), model.getOptionalNullLong());
-
-        assertEquals(Optional.of(Short.valueOf("1")), model.getOptionalShort());
-        assertEquals(Optional.empty(), model.getOptionalNullShort());
-
-        assertEquals(Optional.of(Double.valueOf("1")), model.getOptionalDouble());
-        assertEquals(Optional.empty(), model.getOptionalNullDouble());
-
-        assertEquals(Optional.of(Float.valueOf("1")), model.getOptionalFloat());
-        assertEquals(Optional.empty(), model.getOptionalNullFloat());
-
-        assertEquals(Optional.of(1L), model.getOptionalLong());
-        assertEquals(Optional.empty(), model.getOptionalNullLong());
-
-        assertEquals(Optional.of('1'), model.getOptionalChar());
-        assertEquals(Optional.empty(), model.getOptionalNullChar());
-
-        assertEquals(Optional.of(Boolean.valueOf("true")), model.getOptionalBoolean());
-        assertEquals(Optional.empty(), model.getOptionalNullBoolean());
-
+        /*
         assertEquals(Optional.of(Arrays.asList("foo", "bar", "baz")), model.getOptionalList());
-        assertEquals(Optional.empty(), model.getOptionalNullList());
+        assertEquals(Arrays.asList("foo", "bar", "baz"), model.getOptional2List());
+        */
 
-        assertTrue(model.getOptionalArray().isPresent());
-        assertTrue("qux".equalsIgnoreCase(model.getOptionalArray().get()[0]));
-        assertTrue("quux".equalsIgnoreCase(model.getOptionalArray().get()[1]));
-        assertEquals(Optional.empty(), model.getOptionalNullArray());
     }
 }
diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/OptionalObjectsModel.java b/src/test/java/org/apache/sling/models/testmodels/classes/OptionalObjectsModel.java
index a130e3d..c360004 100644
--- a/src/test/java/org/apache/sling/models/testmodels/classes/OptionalObjectsModel.java
+++ b/src/test/java/org/apache/sling/models/testmodels/classes/OptionalObjectsModel.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sling.models.testmodels.classes;
 
-import java.util.Collection;
+import java.util.List;
 import java.util.Optional;
 import javax.inject.Inject;
 
@@ -27,156 +27,16 @@
 public class OptionalObjectsModel {
 
     @Inject
-    private Optional<String> optionalString;
+    private Optional<List<String>> optionalList;
 
     @Inject
-    private Optional<String> optionalNullString;
+    private List<String> optional2List;
 
-    @Inject
-    private Optional<Byte> optionalByte;
-
-    @Inject
-    private Optional<Byte> optionalNullByte;
-
-    @Inject
-    private Optional<Short> optionalShort;
-
-    @Inject
-    private Optional<Short> optionalNullShort;
-
-    @Inject
-    private Optional<Integer> optionalInteger;
-
-    @Inject
-    private Optional<Integer> optionalNullInteger;
-
-    @Inject
-    private Optional<Long> optionalLong;
-
-    @Inject
-    private Optional<Long> optionalNullLong;
-
-    @Inject
-    private Optional<Float> optionalFloat;
-
-    @Inject
-    private Optional<Float> optionalNullFloat;
-
-    @Inject
-    private Optional<Double> optionalDouble;
-
-    @Inject
-    private Optional<Double> optionalNullDouble;
-
-    @Inject
-    private Optional<Character> optionalChar;
-
-    @Inject
-    private Optional<Character> optionalNullChar;
-
-    @Inject
-    private Optional<Boolean> optionalBoolean;
-
-    @Inject
-    private Optional<Boolean> optionalNullBoolean;
-
-    @Inject
-    private Optional<? extends Collection> optionalList;
-
-    @Inject
-    private Optional<? extends Collection> optionalNullList;
-
-    @Inject
-    private Optional<String[]> optionalArray;
-
-    @Inject
-    private Optional<String[]> optionalNullArray;
-
-    public Optional<String> getOptionalString() {
-        return optionalString;
-    }
-
-    public Optional<String> getOptionalNullString() {
-        return optionalNullString;
-    }
-
-    public Optional<Byte> getOptionalByte() {
-        return optionalByte;
-    }
-
-    public Optional<Byte> getOptionalNullByte() {
-        return optionalNullByte;
-    }
-
-    public Optional<Short> getOptionalShort() {
-        return optionalShort;
-    }
-
-    public Optional<Short> getOptionalNullShort() {
-        return optionalNullShort;
-    }
-
-    public Optional<Integer> getOptionalInteger() {
-        return optionalInteger;
-    }
-
-    public Optional<Integer> getOptionalNullInteger() {
-        return optionalNullInteger;
-    }
-
-    public Optional<Long> getOptionalLong() {
-        return optionalLong;
-    }
-
-    public Optional<Long> getOptionalNullLong() {
-        return optionalNullLong;
-    }
-
-    public Optional<Float> getOptionalFloat() {
-        return optionalFloat;
-    }
-
-    public Optional<Float> getOptionalNullFloat() {
-        return optionalNullFloat;
-    }
-
-    public Optional<Double> getOptionalDouble() {
-        return optionalDouble;
-    }
-
-    public Optional<Double> getOptionalNullDouble() {
-        return optionalNullDouble;
-    }
-
-    public Optional<Character> getOptionalChar() {
-        return optionalChar;
-    }
-
-    public Optional<Character> getOptionalNullChar() {
-        return optionalNullChar;
-    }
-
-    public Optional<Boolean> getOptionalBoolean() {
-        return optionalBoolean;
-    }
-
-    public Optional<Boolean> getOptionalNullBoolean() {
-        return optionalNullBoolean;
-    }
-
-    public Optional<? extends Collection> getOptionalList() {
+    public Optional<List<String>> getOptionalList() {
         return optionalList;
     }
 
-    public Optional<? extends Collection> getOptionalNullList() {
-        return optionalNullList;
-    }
-
-    public Optional<String[]> getOptionalArray() {
-        return optionalArray;
-    }
-
-    public Optional<String[]> getOptionalNullArray() {
-        return optionalNullArray;
+    public List<String> getOptional2List() {
+        return optional2List;
     }
 }