diff --git a/java/javax/el/MapELResolver.java b/java/javax/el/MapELResolver.java
index 0f33814..26e6cce 100644
--- a/java/javax/el/MapELResolver.java
+++ b/java/javax/el/MapELResolver.java
@@ -118,11 +118,12 @@
                 key = itr.next();
                 desc = new FeatureDescriptor();
                 desc.setDisplayName(key.toString());
+                desc.setShortDescription("");
                 desc.setExpert(false);
                 desc.setHidden(false);
                 desc.setName(key.toString());
                 desc.setPreferred(true);
-                desc.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.FALSE);
+                desc.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
                 desc.setValue(TYPE, key.getClass());
                 feats.add(desc);
             }
diff --git a/test/javax/el/TestMapELResolver.java b/test/javax/el/TestMapELResolver.java
new file mode 100644
index 0000000..fa8bb63
--- /dev/null
+++ b/test/javax/el/TestMapELResolver.java
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javax.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestMapELResolver {
+
+    /**
+     * Tests that a null context results in an NPE as per EL Javadoc.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetType01() {
+        MapELResolver mapELResolver = new MapELResolver();
+        mapELResolver.getType(null, new Object(), new Object());
+    }
+
+    /**
+     * Tests that a valid property is not resolved if base is not Map.
+     */
+    @Test
+    public void testGetType02() {
+        doNegativeTest(new Object(), new Object(), MethodUnderTest.GET_TYPE,
+                true);
+    }
+
+    /**
+     * Tests that a valid property is resolved.
+     */
+    @Test
+    public void testGetType03() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Class<?> result = mapELResolver.getType(context, new HashMap<>(),
+                "test");
+
+        Assert.assertEquals(Object.class, result);
+        Assert.assertTrue(context.isPropertyResolved());
+    }
+
+    /**
+     * Tests that a null context results in an NPE as per EL Javadoc.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetValue01() {
+        MapELResolver mapELResolver = new MapELResolver();
+        mapELResolver.getValue(null, new Object(), new Object());
+    }
+
+    /**
+     * Tests that a valid property is not resolved if base is not Map.
+     */
+    @Test
+    public void testGetValue02() {
+        doNegativeTest(new Object(), new Object(), MethodUnderTest.GET_VALUE,
+                true);
+    }
+
+    /**
+     * Tests that a valid property is resolved.
+     */
+    @Test
+    public void testGetValue03() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Map<String, String> map = new HashMap<>();
+        map.put("key", "value");
+        Object result = mapELResolver.getValue(context, map, "key");
+
+        Assert.assertEquals("value", result);
+        Assert.assertTrue(context.isPropertyResolved());
+
+        result = mapELResolver.getValue(context, map, "unknown-key");
+
+        Assert.assertNull(result);
+        Assert.assertTrue(context.isPropertyResolved());
+    }
+
+    /**
+     * Tests that a null context results in an NPE as per EL Javadoc.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testSetValue01() {
+        MapELResolver mapELResolver = new MapELResolver();
+        mapELResolver.setValue(null, new Object(), new Object(), new Object());
+    }
+
+    /**
+     * Tests that a valid property is not set if base is not Map.
+     */
+    @Test
+    public void testSetValue02() {
+        doNegativeTest(new Object(), new Object(), MethodUnderTest.SET_VALUE,
+                false);
+    }
+
+    /**
+     * Tests that an exception is thrown when readOnly is true.
+     */
+    @Test(expected = PropertyNotWritableException.class)
+    public void testSetValue03() {
+        MapELResolver mapELResolver = new MapELResolver(true);
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        mapELResolver.setValue(context, new HashMap<>(), new Object(),
+                new Object());
+    }
+
+    /**
+     * Tests that a valid property is set.
+     */
+    @Test
+    public void testSetValue04() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Map<String, String> map = new HashMap<>();
+        mapELResolver.setValue(context, map, "key", "value");
+
+        Assert.assertEquals("value",
+                mapELResolver.getValue(context, map, "key"));
+        Assert.assertTrue(context.isPropertyResolved());
+    }
+
+    /**
+     * Tests that an exception is thrown when the map is not modifiable.
+     */
+    @Test(expected = PropertyNotWritableException.class)
+    public void testSetValue05() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Map<Object, Object> map = Collections.unmodifiableMap(new HashMap<>());
+        mapELResolver.setValue(context, map, "key", "value");
+    }
+
+    /**
+     * Tests that a null context results in an NPE as per EL Javadoc.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsReadOnly01() {
+        MapELResolver mapELResolver = new MapELResolver();
+        mapELResolver.isReadOnly(null, new Object(), new Object());
+    }
+
+    /**
+     * Tests that the propertyResolved is false if base is not Map.
+     */
+    @Test
+    public void testIsReadOnly02() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        boolean result = mapELResolver.isReadOnly(context, new Object(),
+                new Object());
+
+        Assert.assertFalse(result);
+        Assert.assertFalse(context.isPropertyResolved());
+
+        mapELResolver = new MapELResolver(true);
+
+        result = mapELResolver.isReadOnly(context, new Object(), new Object());
+
+        Assert.assertTrue(result);
+        Assert.assertFalse(context.isPropertyResolved());
+    }
+
+    /**
+     * Tests that if the MapELResolver is constructed with readOnly the method
+     * will return always true, otherwise false.
+     */
+    @Test
+    public void testIsReadOnly03() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        boolean result = mapELResolver.isReadOnly(context, new HashMap<>(),
+                new Object());
+
+        Assert.assertFalse(result);
+        Assert.assertTrue(context.isPropertyResolved());
+
+        mapELResolver = new MapELResolver(true);
+
+        result = mapELResolver.isReadOnly(context, new HashMap<>(),
+                new Object());
+
+        Assert.assertTrue(result);
+        Assert.assertTrue(context.isPropertyResolved());
+    }
+
+    /**
+     * Tests that the readOnly is true always when the map is not modifiable.
+     */
+    @Test
+    public void testIsReadOnly04() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Map<Object, Object> map = Collections.unmodifiableMap(new HashMap<>());
+        boolean result = mapELResolver.isReadOnly(context, map, new Object());
+
+        Assert.assertTrue(result);
+        Assert.assertTrue(context.isPropertyResolved());
+    }
+
+    /**
+     * Tests that a valid FeatureDescriptors are not returned if base is not
+     * Map.
+     */
+    @Test
+    public void testGetFeatureDescriptors01() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Iterator<FeatureDescriptor> result = mapELResolver
+                .getFeatureDescriptors(context, new Object());
+
+        Assert.assertNull(result);
+    }
+
+    /**
+     * Tests that a valid FeatureDescriptors are returned.
+     */
+    @Test
+    public void testGetFeatureDescriptors02() {
+        MapELResolver mapELResolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Map<String, String> map = new HashMap<>();
+        map.put("key", "value");
+        Iterator<FeatureDescriptor> result = mapELResolver
+                .getFeatureDescriptors(context, map);
+
+        while (result.hasNext()) {
+            FeatureDescriptor featureDescriptor = result.next();
+            Assert.assertEquals("key", featureDescriptor.getDisplayName());
+            Assert.assertEquals("key", featureDescriptor.getName());
+            Assert.assertEquals("", featureDescriptor.getShortDescription());
+            Assert.assertFalse(featureDescriptor.isExpert());
+            Assert.assertFalse(featureDescriptor.isHidden());
+            Assert.assertTrue(featureDescriptor.isPreferred());
+            Assert.assertEquals("key".getClass(),
+                    featureDescriptor.getValue(ELResolver.TYPE));
+            Assert.assertEquals(Boolean.TRUE, featureDescriptor
+                    .getValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME));
+        }
+    }
+
+    private void doNegativeTest(Object base, Object trigger,
+            MethodUnderTest method, boolean checkResult) {
+        MapELResolver resolver = new MapELResolver();
+        ELContext context = new StandardELContext(
+                ELManager.getExpressionFactory());
+
+        Object result = null;
+        switch (method) {
+        case GET_VALUE: {
+            result = resolver.getValue(context, base, trigger);
+            break;
+        }
+        case SET_VALUE: {
+            resolver.setValue(context, base, trigger, new Object());
+            break;
+        }
+        case GET_TYPE: {
+            result = resolver.getType(context, base, trigger);
+            break;
+        }
+        default: {
+            // Should never happen
+            Assert.fail("Missing case for method");
+        }
+        }
+
+        if (checkResult) {
+            Assert.assertNull(result);
+        }
+        Assert.assertFalse(context.isPropertyResolved());
+    }
+
+    private static enum MethodUnderTest {
+        GET_VALUE, SET_VALUE, GET_TYPE
+    }
+}
