SLING-9774 The ValueMapUtil#merge behavior is different from the
deprecated CompositeValueMap
diff --git a/src/main/java/org/apache/sling/api/wrappers/impl/MergingValueMap.java b/src/main/java/org/apache/sling/api/wrappers/impl/MergingValueMap.java
index 9e2bef3..6cd2e5f 100644
--- a/src/main/java/org/apache/sling/api/wrappers/impl/MergingValueMap.java
+++ b/src/main/java/org/apache/sling/api/wrappers/impl/MergingValueMap.java
@@ -18,10 +18,6 @@
  */
 package org.apache.sling.api.wrappers.impl;
 
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ValueMapUtil;
-import org.jetbrains.annotations.NotNull;
-
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -29,10 +25,15 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapUtil;
+import org.jetbrains.annotations.NotNull;
+
 /**
  * Merge provided {@code ValueMaps} into a single view {@code ValueMap} that aggregates
  * all key-value pairs of the given maps. The value for a key-value pair is taken from
@@ -108,12 +109,42 @@
     @Override
     public Object get(Object key) {
         return valueMaps.stream()
-                .map(vm -> vm.get(key))
+                .map(vm -> getOrEmpty(vm, key)) // SLING-9774
                 .filter(Objects::nonNull)
                 .findFirst()
+                .filter(Optional::isPresent)    // skip if Optional#empty
+                .map(Optional::get)             // dig the value out of the Optional
                 .orElse(null);
     }
 
+    /**
+     * SLING-9774 - Returns an {@code Optional} describing the value in the map value for
+     * the supplied key.  Special handling is supplied for an existing key that
+     * resolves to a null value.
+     *
+     * @param vm the map to get the value from
+     * @param key the key to get the value for
+     * @return an {@code Optional} with a present value if the specified value
+     * is non-null, otherwise if the map contains the key then an empty {@code Optional},
+     * otherwise null
+     */
+    private Optional<Object> getOrEmpty(ValueMap vm, Object key) {
+        Optional<Object> opt = null;
+        Object value = vm.get(key);
+        if (value == null) {
+            // check if the null value is for a real entry
+            if (vm.containsKey(key)) {
+                // key exists so return the empty Optional
+                //   instead of null
+                opt = Optional.empty();
+            }
+        } else {
+            // not null so just wrap the value
+            opt = Optional.of(value);
+        }
+        return opt;
+    }
+
     @NotNull
     @Override
     public Set<String> keySet() {
diff --git a/src/test/java/org/apache/sling/api/resource/impl/ValueMapUtilMergeTest.java b/src/test/java/org/apache/sling/api/resource/impl/ValueMapUtilMergeTest.java
index 470955a..c107cdb 100644
--- a/src/test/java/org/apache/sling/api/resource/impl/ValueMapUtilMergeTest.java
+++ b/src/test/java/org/apache/sling/api/resource/impl/ValueMapUtilMergeTest.java
@@ -157,6 +157,25 @@
         typicalVM().clear();
     }
 
+    /**
+     * SLING-9774 - Test that a key=null value in the first map is used
+     * instead of the key=value entry in the second map
+     */
+    @Test
+    public void testNullValueForExistingKey() {
+        // value is null in the first map
+        ValueMap v1 = createValueMap("k1", null);
+
+        // value is not null in the second map
+        ValueMap v2 = createValueMap("k1", "11");
+
+        // expected to get null value since the first
+        //   map had a real key
+        ValueMap merge = merge(v1, v2);
+        assertTrue(merge.containsKey("k1"));
+        assertNull(merge.get("k1"));
+    }
+
     private static ValueMap createValueMap(Object... pairs) {
         ValueMap vm = new ValueMapDecorator(new HashMap<>());
         for (int i = 0; i < pairs.length; i += 2) {