content: package hu.akarnokd.rxjava2;
  
  import java.util.Iterator;
  import java.util.concurrent.atomic.*;
  
  import org.reactivestreams.*;
  
  import io.reactivex.*;
  import io.reactivex.disposables.Disposable;
  import io.reactivex.exceptions.Exceptions;
  import io.reactivex.functions.Function;
  import io.reactivex.internal.disposables.DisposableHelper;
  import io.reactivex.internal.util.BackpressureHelper;
  import io.reactivex.rxjava3.internal.subscriptions.SubscriptionHelper;
  
  public final class SingleFlatMapIterableFlowable<T, R> extends Flowable<R> {
  
      final SingleSource<T> source;
  
      final Function<? super T, ? extends Iterable<? extends R>> mapper;
  
      public SingleFlatMapIterableFlowable(SingleSource<T> source,
              Function<? super T, ? extends Iterable<? extends R>> mapper) {
          this.source = source;
          this.mapper = mapper;
      }
  
      @Override
      protected void subscribeActual(Subscriber<? super R> s) {
          source.subscribe(new FlatMapIterableObserver<T, R>(s, mapper));
      }
  
      static final class FlatMapIterableObserver<T, R>
      extends AtomicInteger
      implements SingleObserver<T>, Subscription {
  
          private static final long serialVersionUID = -8938804753851907758L;
  
          final Subscriber<? super R> actual;
  
          final Function<? super T, ? extends Iterable<? extends R>> mapper;
  
          final AtomicLong requested;
  
          Disposable d;
  
          volatile Iterator<? extends R> it;
  
          volatile boolean cancelled;
  
          FlatMapIterableObserver(Subscriber<? super R> actual,
                  Function<? super T, ? extends Iterable<? extends R>> mapper) {
              this.actual = actual;
              this.mapper = mapper;
              this.requested = new AtomicLong();
          }
  
          @Override
          public void onSubscribe(Disposable d) {
              if (DisposableHelper.validate(this.d, d)) {
                  this.d = d;
  
                  actual.onSubscribe(this);
              }
          }
  
          @Override
          public void onSuccess(T value) {
              Iterator<? extends R> iter;
              boolean has;
              try {
  
                  iter = mapper.apply(value).iterator();
  
                  has = iter.hasNext();
              } catch (Throwable ex) {
                  Exceptions.throwIfFatal(ex);
                  actual.onError(ex);
                  return;
              }
  
              if (!has) {
                  actual.onComplete();
                  return;
              }
              this.it = iter;
              drain();
          }
  
          @Override
          public void onError(Throwable e) {
              d = DisposableHelper.DISPOSED;
              actual.onError(e);
          }
  
          @Override
          public void request(long n) {
              if (SubscriptionHelper.validate(n)) {
                  BackpressureHelper.add(requested, n);
                  drain();
              }
          }
  
          @Override
          public void cancel() {
              cancelled = true;
              d.dispose();
              d = DisposableHelper.DISPOSED;
          }
  
          void drain() {
              if (getAndIncrement() != 0) {
                  return;
              }
  
              int missed = 1;
  
              Iterator<? extends R> iter = this.it;
  
              Subscriber<? super R> a = actual;
  
              for (;;) {
  
                  if (iter != null) {
                      long r = requested.get();
                      long e = 0L;
  
                      if (r == Long.MAX_VALUE) {
                          for (;;) {
                              if (cancelled) {
                                  return;
                              }
  
                              R v;
  
                              try {
                                  v = iter.next();
                              } catch (Throwable ex) {
                                  Exceptions.throwIfFatal(ex);
                                  a.onError(ex);
                                  return;
                              }
  
                              a.onNext(v);
  
                              if (cancelled) {
                                  return;
                              }
  
  
                              boolean b;
  
                              try {
                                  b = iter.hasNext();
                              } catch (Throwable ex) {
                                  Exceptions.throwIfFatal(ex);
                                  a.onError(ex);
                                  return;
                              }
  
                              if (!b) {
                                  a.onComplete();
                                  return;
                              }
                          }
                      }
  
                      while (e != r) {
                          if (cancelled) {
                              return;
                          }
  
                          R v;
  
                          try {
                              v = iter.next();
                          } catch (Throwable ex) {
                              Exceptions.throwIfFatal(ex);
                              a.onError(ex);
                              return;
                          }
  
                          a.onNext(v);
  
                          if (cancelled) {
                              return;
                          }
  
  
                          e++;
  
                          boolean b;
  
                          try {
                              b = iter.hasNext();
                          } catch (Throwable ex) {
                              Exceptions.throwIfFatal(ex);
                              a.onError(ex);
                              return;
                          }
  
                          if (!b) {
                              a.onComplete();
                              return;
                          }
                      }
  
                      if (e != 0L) {
                          BackpressureHelper.produced(requested, e);
                      }
                  }
  
                  missed = addAndGet(-missed);
                  if (missed == 0) {
                      break;
                  }
  
                  if (iter == null) {
                      iter = it;
                  }
              }
          }
      }
  }
  