class MultiPartDecoder implements Processor<DataChunk, ReadableBodyPart> {

    @Override
    public void subscribe(Subscriber<? super ReadableBodyPart> subscriber) {
        Objects.requireNonNull(subscriber);
        if (!halfInit(UPSTREAM_INIT)) {
            Multi.<ReadableBodyPart>error(new IllegalStateException("Only one Subscriber allowed"))
                 .subscribe(subscriber);
            return;
        }
        this.downstream = subscriber;

        // contenders < 0, so any part request will be deferred
        // drain() will not request anything from upstream until the second deferredInit() invocation witnesses
        // that upstream is set
        downstream.onSubscribe(new Subscription() {

            @Override
            public void request(long n) {
                long curr = n <= 0
                            ? partsRequested.getAndSet(-1)
                            : partsRequested.getAndUpdate(v -> Long.MAX_VALUE - v > n
                            ? v + n : v < 0 ? v : Long.MAX_VALUE);
                if (curr == 0) {
                    drain();
                }
            }

            @Override
            public void cancel() {
                cancelled = true;
                if (partsRequested.getAndSet(-1) == 0) {
                    drain();
                }
            }
        });

        deferredInit();
    }

      MultiPartDecoder(String boundary, MessageBodyReaderContext context);

}