@SuppressWarnings("unchecked")
    private Stream<Object> resolveValue(Object obj) {
        if (obj == null) {
            return Stream.empty();
        } else if (obj instanceof Map) { // TODO not sure if we also need to inspect the keys. Seem a tad unlikely.
            return ((Map<Object, Object>) obj).values().stream();
        } else if (obj instanceof Collection) {
            return ((Collection<Object>) obj).stream();
        } else if (obj instanceof Object[]) {
            return Arrays.stream((Object[])obj);
        } else {
            return Stream.of(obj);
        }
    }
Chase object graph for all @BlobReference strings.
<ul>
  <li>Starting with root and until no entries remain: pop entry off stack, this becomes <code>currentNode</code></li>
  <li>Iterate through every field in <code>currentNode</code>.</li>
  <li>If a field is a <code>String</code> and annotated with <code>BlobReference</code>, it is captured.</li>
  <li>Any non-String type that begins with <code>io.apiman</code> is pushed onto the stack. All other types are ignored.</li>
</ul>
TODO(msavy): Add cache or use Jandex to avoid repeated expensive reflection and iteration.
Simple!
manager/api/rest-impl/src/main/java/io/apiman/manager/api/rest/interceptors/BlobResourceInterceptorProvider.java