code: Optional<ConfigValue<T>> resolveNameRecursively(Optional<String> name, Function<Optional<String>, Optional<ConfigValue<T>>> resolver) {
      Optional<ConfigValue<T>> value = resolver.apply(name);
      if (value.isPresent()) {
        return value;
      } else {
        if (name.isPresent()) {
          return resolveNameRecursively(name.filter(s -> s.lastIndexOf(':') > 0).map(s -> s.substring(0, s.lastIndexOf(':'))), resolver);
        } else {
          return Optional.empty();
        }
      }
    }
docs: This method recursively uses given resolver to resolve a config by given name taking into account
  syntax of sub-resource names. For example, for given name: Optional.of("foo:bar:baz") it will make
  the following resolver calls:
  - resolver(Optional.of("foo:bar:baz"))
  - resolver(Optional.of("foo:bar"))
  - resolver(Optional.of("foo"))
  - resolver(Optional.empty())