public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
        return () -> {
            Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);

            @SuppressWarnings("unchecked")
            T current = (T) scopedObjects.get(key);
            if (current == null && !scopedObjects.containsKey(key)) {
                current = unscoped.get();

                // don't remember proxies; these exist only to serve circular dependencies
                if (Scopes.isCircularProxy(current)) {
                    return current;
                }

                scopedObjects.put(key, current);
            }
            return current;
        };
    }
Scopes a single execution of a block of code. Apply this scope with a
try/finally block: <pre><code>
<p>
  scope.enter();
  try {
    // explicitly seed some seed objects...
    scope.seed(Key.get(SomeObject.class), someObject);
    // create and access scoped objects
  } finally {
    scope.exit();
  }
</code></pre>
<p>
The scope can be initialized with one or more seed threadLocal by calling
<code>seed(key, value)</code> before the injector will be called upon to
provide for this key. A typical use is for a servlet filter to enter/exit the
scope, representing a Request Scope, and seed HttpServletRequest and
HttpServletResponse.  For each key inserted with seed(), you must include a
corresponding binding:
<pre><code>
  bind(key)
      .toProvider(SimpleScope.&lt;KeyClass&gt;seededKeyProvider())
      .in(ScopeAnnotation.class);
</code></pre>

@author Jesse Wilson
@author Fedor Karpelevitch
stroom-util/src/main/java/stroom/util/pipeline/scope/PipelineScope.java