@Override
    public void onSubscribe(Subscription s) {
      if (SubscriptionHelper.validateSubscription(this.s, s)) {
        return;
      }
      this.s = s;

      Subscriber<? super U> actual = this.actual;

      U b;

      try {
        b = bufferSupplier.get();
      } catch (Throwable e) {
        cancelled = true;
        s.cancel();
        EmptySubscription.error(e, actual);
        return;
      }

      if (b == null) {
        cancelled = true;
        s.cancel();
        EmptySubscription.error(new NullPointerException("The buffer supplied is null"), actual);
        return;
      }
      buffer = b;

      Publisher<B> boundary;

      try {
        boundary = boundarySupplier.get();
      } catch (Throwable ex) {
        cancelled = true;
        s.cancel();
        EmptySubscription.error(ex, actual);
        return;
      }

      if (boundary == null) {
        cancelled = true;
        s.cancel();
        EmptySubscription.error(
            new NullPointerException("The boundary publisher supplied is null"), actual);
        return;
      }

      BufferBoundarySubscriber<T, U, B> bs = new BufferBoundarySubscriber<T, U, B>(this);
      other = bs;

      actual.onSubscribe(this);

      if (!cancelled) {
        s.request(Long.MAX_VALUE);

        boundary.subscribe(bs);
      }
    }
    void next() {

      Disposable o = other;

      U next;

      try {
        next = bufferSupplier.get();
      } catch (Throwable e) {
        cancel();
        actual.onError(e);
        return;
      }

      if (next == null) {
        cancel();
        actual.onError(new NullPointerException("The buffer supplied is null"));
        return;
      }

      Publisher<B> boundary;

      try {
        boundary = boundarySupplier.get();
      } catch (Throwable ex) {
        cancelled = true;
        s.cancel();
        actual.onError(ex);
        return;
      }

      if (boundary == null) {
        cancelled = true;
        s.cancel();
        actual.onError(new NullPointerException("The boundary publisher supplied is null"));
        return;
      }

      BufferBoundarySubscriber<T, U, B> bs = new BufferBoundarySubscriber<T, U, B>(this);

      if (!OTHER.compareAndSet(this, o, bs)) {
        return;
      }

      U b;
      synchronized (this) {
        b = buffer;
        if (b == null) {
          return;
        }
        buffer = next;
      }

      boundary.subscribe(bs);

      fastpathEmitMax(b, false, this);
    }
    @Override
    public void cancel() {
      if (!cancelled) {
        cancelled = true;
        s.cancel();
        disposeOther();

        if (enter()) {
          queue.clear();
        }
      }
    }
 @Override
 public void dispose() {
   s.cancel();
   disposeOther();
 }