public <R> TraceContext.Injector<R> newInjector(Setter<R, String> setter) {
    if (setter == null) throw new NullPointerException("setter == null");
    if (setter instanceof RemoteSetter) {
      RemoteSetter<?> remoteSetter = (RemoteSetter<?>) setter;
      switch (remoteSetter.spanKind()) {
        case CLIENT:
          return new RemoteInjector<R>(setter, clientInjectorFunction);
        case PRODUCER:
          return new RemoteInjector<R>(setter, producerInjectorFunction);
        case CONSUMER:
          return new RemoteInjector<R>(setter, consumerInjectorFunction);
        default: // SERVER is nonsense as it cannot be injected
      }
    }
    return new DeferredInjector<R>(setter, this);
  }
@Test void twoFunctions_injects_deferred() {
    DeferredInjector<Object> deferredInjector =
        (DeferredInjector<Object>) twoFunctions.newInjector(setter);

    for (Kind kind : injectableKinds) {
      when(request.spanKind()).thenReturn(kind);

      deferredInjector.inject(context, request);
      assertThat(oneCount.getAndSet(0)).isOne();
      assertThat(twoCount.getAndSet(0)).isOne();
    }

    deferredInjector.inject(context, notRequest);
    assertThat(oneCount.getAndSet(0)).isOne();
    assertThat(twoCount.getAndSet(0)).isOne();

    // works with nonsense
    when(request.spanKind()).thenReturn(Kind.SERVER);
    deferredInjector.inject(context, request);
    assertThat(oneCount.getAndSet(0)).isOne();
    assertThat(twoCount.getAndSet(0)).isOne();
  }