Bug 411147 - ServiceLocator#getService(Class) may register an invalid service object; IEclipseContext#get(Class) does not handle NOT_A_VALUE
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java
index 4a4f0c8..e10d32d 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java
@@ -67,7 +67,8 @@
 	 * @param contextKey
 	 *            The context key used to find this function; may be {@code null} such
 	 *            as if invoked directly.
-	 * @return The concrete value.
+	 * @return The concrete value. Implementations may return {@link org.eclipse.e4.core.di.IInjector#NOT_A_VALUE}
+	 * 		to cause lookup to continue up the context hierarchy.
 	 */
 	public Object compute(IEclipseContext context, String contextKey);
 
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
index 5552533..6203a16 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
@@ -217,8 +217,12 @@
 	public Object internalGet(EclipseContext originatingContext, String name, boolean local) {
 		if (this == originatingContext) {
 			ValueComputation valueComputation = localValueComputations.get(name);
-			if (valueComputation != null)
-				return valueComputation.get();
+			if (valueComputation != null) {
+				Object result = valueComputation.get();
+				if (result != IInjector.NOT_A_VALUE) {
+					return result;
+				}
+			}
 		}
 
 		Object result = null;
@@ -670,8 +674,12 @@
 		Map<String, Object> result = new HashMap<String, Object>(localValueComputations.size());
 		for (String string : localValueComputations.keySet()) {
 			ValueComputation vc = localValueComputations.get(string);
-			if (vc != null)
-				result.put(string, vc.get());
+			if (vc != null) {
+				Object r = vc.get();
+				if (r != IInjector.NOT_A_VALUE) {
+					result.put(string, vc.get());
+				}
+			}
 		}
 		return result;
 	}
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java
index 1423f4c..21e186a 100644
--- a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java
+++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java
@@ -330,6 +330,10 @@
 			}
 		});
 
+		// must call several times as the underlying ValueComputation wrapper is
+		// created on the first time, but re-used for subsequent calls.
+		assertNull(context.get("x"));
+		assertNull(context.get("x"));
 		assertNull(context.get("x"));
 		context.dispose();
 	}