content: /**
   * Copyright (c) 2016-present, RxJava Contributors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
   * compliance with the License. You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software distributed under the License is
   * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
   * the License for the specific language governing permissions and limitations under the License.
   */
  package io.reactivex.observable;
  
  import java.util.concurrent.*;
  
  import io.reactivex.common.*;
  import io.reactivex.common.annotations.*;
  import io.reactivex.common.functions.*;
  import io.reactivex.common.internal.functions.ObjectHelper;
  import io.reactivex.common.internal.schedulers.*;
  import io.reactivex.common.internal.utils.ExceptionHelper;
  /**
   * Utility class to inject handlers to certain standard RxJava operations.
   */
  public final class RxJavaObservablePlugins {
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile Function<? super ConnectableObservable, ? extends ConnectableObservable> onConnectableObservableAssembly;
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile Function<? super Maybe, ? extends Maybe> onMaybeAssembly;
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile Function<? super Single, ? extends Single> onSingleAssembly;
  
      static volatile Function<? super Completable, ? extends Completable> onCompletableAssembly;
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile BiFunction<? super Maybe, ? super MaybeObserver, ? extends MaybeObserver> onMaybeSubscribe;
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile BiFunction<? super Observable, ? super Observer, ? extends Observer> onObservableSubscribe;
  
      @SuppressWarnings("rawtypes")
      @Nullable
      static volatile BiFunction<? super Single, ? super SingleObserver, ? extends SingleObserver> onSingleSubscribe;
  
      @Nullable
      static volatile BiFunction<? super Completable, ? super CompletableObserver, ? extends CompletableObserver> onCompletableSubscribe;
  
      /** Prevents changing the plugins. */
      static volatile boolean lockdown;
  
      /**
       * Prevents changing the plugins from then on.
       * <p>This allows container-like environments to prevent clients
       * messing with plugins.
       */
      public static void lockdown() {
          lockdown = true;
      }
  
      /**
       * Returns true if the plugins were locked down.
       * @return true if the plugins were locked down
       */
      public static boolean isLockdown() {
          return lockdown;
      }
  
      /**
       * Removes all handlers and resets to default behavior.
       */
      public static void reset() {
          setOnObservableAssembly(null);
          setOnObservableSubscribe(null);
  
          setOnSingleAssembly(null);
          setOnSingleSubscribe(null);
  
          setOnCompletableAssembly(null);
          setOnCompletableSubscribe(null);
  
          setOnConnectableObservableAssembly(null);
  
          setOnMaybeAssembly(null);
          setOnMaybeSubscribe(null);
      }
  
      /**
       * Revokes the lockdown, only for testing purposes.
       */
      /* test. */static void unlock() {
          lockdown = false;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      public static Function<? super Completable, ? extends Completable> getOnCompletableAssembly() {
          return onCompletableAssembly;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      public static BiFunction<? super Completable, ? super CompletableObserver, ? extends CompletableObserver> getOnCompletableSubscribe() {
          return onCompletableSubscribe;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static BiFunction<? super Maybe, ? super MaybeObserver, ? extends MaybeObserver> getOnMaybeSubscribe() {
          return onMaybeSubscribe;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static Function<? super Maybe, ? extends Maybe> getOnMaybeAssembly() {
          return onMaybeAssembly;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static Function<? super Single, ? extends Single> getOnSingleAssembly() {
          return onSingleAssembly;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static BiFunction<? super Single, ? super SingleObserver, ? extends SingleObserver> getOnSingleSubscribe() {
          return onSingleSubscribe;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static Function<? super Observable, ? extends Observable> getOnObservableAssembly() {
          return onObservableAssembly;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static Function<? super ConnectableObservable, ? extends ConnectableObservable> getOnConnectableObservableAssembly() {
          return onConnectableObservableAssembly;
      }
  
      /**
       * Returns the current hook function.
       * @return the hook function, may be null
       */
      @Nullable
      @SuppressWarnings("rawtypes")
      public static BiFunction<? super Observable, ? super Observer, ? extends Observer> getOnObservableSubscribe() {
          return onObservableSubscribe;
      }
  
      /**
       * Sets the specific hook function.
       * @param onCompletableAssembly the hook function to set, null allowed
       */
      public static void setOnCompletableAssembly(@Nullable Function<? super Completable, ? extends Completable> onCompletableAssembly) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onCompletableAssembly = onCompletableAssembly;
      }
  
      /**
       * Sets the specific hook function.
       * @param onCompletableSubscribe the hook function to set, null allowed
       */
      public static void setOnCompletableSubscribe(
              @Nullable BiFunction<? super Completable, ? super CompletableObserver, ? extends CompletableObserver> onCompletableSubscribe) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onCompletableSubscribe = onCompletableSubscribe;
      }
  
      /**
       * Sets the specific hook function.
       * @param onMaybeAssembly the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnMaybeAssembly(@Nullable Function<? super Maybe, ? extends Maybe> onMaybeAssembly) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onMaybeAssembly = onMaybeAssembly;
      }
  
      /**
       * Sets the specific hook function.
       * @param onMaybeSubscribe the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnMaybeSubscribe(@Nullable BiFunction<? super Maybe, MaybeObserver, ? extends MaybeObserver> onMaybeSubscribe) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onMaybeSubscribe = onMaybeSubscribe;
      }
  
      /**
       * Sets the specific hook function.
       * @param onObservableAssembly the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnObservableAssembly(@Nullable Function<? super Observable, ? extends Observable> onObservableAssembly) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onObservableAssembly = onObservableAssembly;
      }
  
      /**
       * Sets the specific hook function.
       * @param onConnectableObservableAssembly the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnConnectableObservableAssembly(@Nullable Function<? super ConnectableObservable, ? extends ConnectableObservable> onConnectableObservableAssembly) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onConnectableObservableAssembly = onConnectableObservableAssembly;
      }
  
      /**
       * Sets the specific hook function.
       * @param onObservableSubscribe the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnObservableSubscribe(
              @Nullable BiFunction<? super Observable, ? super Observer, ? extends Observer> onObservableSubscribe) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onObservableSubscribe = onObservableSubscribe;
      }
  
      /**
       * Sets the specific hook function.
       * @param onSingleAssembly the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnSingleAssembly(@Nullable Function<? super Single, ? extends Single> onSingleAssembly) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onSingleAssembly = onSingleAssembly;
      }
  
      /**
       * Sets the specific hook function.
       * @param onSingleSubscribe the hook function to set, null allowed
       */
      @SuppressWarnings("rawtypes")
      public static void setOnSingleSubscribe(@Nullable BiFunction<? super Single, ? super SingleObserver, ? extends SingleObserver> onSingleSubscribe) {
          if (lockdown) {
              throw new IllegalStateException("Plugins can't be changed anymore");
          }
          RxJavaObservablePlugins.onSingleSubscribe = onSingleSubscribe;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @param observer the observer
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> Observer<? super T> onSubscribe(@NonNull Observable<T> source, @NonNull Observer<? super T> observer) {
          BiFunction<? super Observable, ? super Observer, ? extends Observer> f = onObservableSubscribe;
          if (f != null) {
              return apply(f, source, observer);
          }
          return observer;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @param observer the observer
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> SingleObserver<? super T> onSubscribe(@NonNull Single<T> source, @NonNull SingleObserver<? super T> observer) {
          BiFunction<? super Single, ? super SingleObserver, ? extends SingleObserver> f = onSingleSubscribe;
          if (f != null) {
              return apply(f, source, observer);
          }
          return observer;
      }
  
      /**
       * Calls the associated hook function.
       * @param source the hook's input value
       * @param observer the observer
       * @return the value returned by the hook
       */
      @NonNull
      public static CompletableObserver onSubscribe(@NonNull Completable source, @NonNull CompletableObserver observer) {
          BiFunction<? super Completable, ? super CompletableObserver, ? extends CompletableObserver> f = onCompletableSubscribe;
          if (f != null) {
              return apply(f, source, observer);
          }
          return observer;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @param subscriber the subscriber
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> MaybeObserver<? super T> onSubscribe(@NonNull Maybe<T> source, @NonNull MaybeObserver<? super T> subscriber) {
          BiFunction<? super Maybe, ? super MaybeObserver, ? extends MaybeObserver> f = onMaybeSubscribe;
          if (f != null) {
              return apply(f, source, subscriber);
          }
          return subscriber;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> Maybe<T> onAssembly(@NonNull Maybe<T> source) {
          Function<? super Maybe, ? extends Maybe> f = onMaybeAssembly;
          if (f != null) {
              return apply(f, source);
          }
          return source;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
          Function<? super Observable, ? extends Observable> f = onObservableAssembly;
          if (f != null) {
              return apply(f, source);
          }
          return source;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> ConnectableObservable<T> onAssembly(@NonNull ConnectableObservable<T> source) {
          Function<? super ConnectableObservable, ? extends ConnectableObservable> f = onConnectableObservableAssembly;
          if (f != null) {
              return apply(f, source);
          }
          return source;
      }
  
      /**
       * Calls the associated hook function.
       * @param <T> the value type
       * @param source the hook's input value
       * @return the value returned by the hook
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @NonNull
      public static <T> Single<T> onAssembly(@NonNull Single<T> source) {
          Function<? super Single, ? extends Single> f = onSingleAssembly;
          if (f != null) {
              return apply(f, source);
          }
          return source;
      }
  
      /**
       * Calls the associated hook function.
       * @param source the hook's input value
       * @return the value returned by the hook
       */
      @NonNull
      public static Completable onAssembly(@NonNull Completable source) {
          Function<? super Completable, ? extends Completable> f = onCompletableAssembly;
          if (f != null) {
              return apply(f, source);
          }
          return source;
      }
  
      /**
       * Create an instance of the default {@link Scheduler} used for {@link Schedulers#computation()}
       * except using {@code threadFactory} for thread creation.
       * <p>History: 2.0.5 - experimental
       * @param threadFactory thread factory to use for creating worker threads. Note that this takes precedence over any
       *                      system properties for configuring new thread creation. Cannot be null.
       * @return the created Scheduler instance
       * @since 2.1
       */
      @NonNull
      public static Scheduler createComputationScheduler(@NonNull ThreadFactory threadFactory) {
          return new ComputationScheduler(ObjectHelper.requireNonNull(threadFactory, "threadFactory is null"));
      }
  
      /**
       * Create an instance of the default {@link Scheduler} used for {@link Schedulers#io()}
       * except using {@code threadFactory} for thread creation.
       * <p>History: 2.0.5 - experimental
       * @param threadFactory thread factory to use for creating worker threads. Note that this takes precedence over any
       *                      system properties for configuring new thread creation. Cannot be null.
       * @return the created Scheduler instance
       * @since 2.1
       */
      @NonNull
      public static Scheduler createIoScheduler(@NonNull ThreadFactory threadFactory) {
          return new IoScheduler(ObjectHelper.requireNonNull(threadFactory, "threadFactory is null"));
      }
  
      /**
       * Create an instance of the default {@link Scheduler} used for {@link Schedulers#newThread()}
       * except using {@code threadFactory} for thread creation.
       * <p>History: 2.0.5 - experimental
       * @param threadFactory thread factory to use for creating worker threads. Note that this takes precedence over any
       *                      system properties for configuring new thread creation. Cannot be null.
       * @return the created Scheduler instance
       * @since 2.1
       */
      @NonNull
      public static Scheduler createNewThreadScheduler(@NonNull ThreadFactory threadFactory) {
          return new NewThreadScheduler(ObjectHelper.requireNonNull(threadFactory, "threadFactory is null"));
      }
  
      /**
       * Create an instance of the default {@link Scheduler} used for {@link Schedulers#single()}
       * except using {@code threadFactory} for thread creation.
       * <p>History: 2.0.5 - experimental
       * @param threadFactory thread factory to use for creating worker threads. Note that this takes precedence over any
       *                      system properties for configuring new thread creation. Cannot be null.
       * @return the created Scheduler instance
       * @since 2.1
       */
      @NonNull
      public static Scheduler createSingleScheduler(@NonNull ThreadFactory threadFactory) {
          return new SingleScheduler(ObjectHelper.requireNonNull(threadFactory, "threadFactory is null"));
      }
  
      /**
       * Wraps the call to the function in try-catch and propagates thrown
       * checked exceptions as RuntimeException.
       * @param <T> the input type
       * @param <R> the output type
       * @param f the function to call, not null (not verified)
       * @param t the parameter value to the function
       * @return the result of the function call
       */
      @NonNull
      static <T, R> R apply(@NonNull Function<T, R> f, @NonNull T t) {
          try {
              return f.apply(t);
          } catch (Throwable ex) {
              throw ExceptionHelper.wrapOrThrow(ex);
          }
      }
  
      /**
       * Wraps the call to the function in try-catch and propagates thrown
       * checked exceptions as RuntimeException.
       * @param <T> the first input type
       * @param <U> the second input type
       * @param <R> the output type
       * @param f the function to call, not null (not verified)
       * @param t the first parameter value to the function
       * @param u the second parameter value to the function
       * @return the result of the function call
       */
      @NonNull
      static <T, U, R> R apply(@NonNull BiFunction<T, U, R> f, @NonNull T t, @NonNull U u) {
          try {
              return f.apply(t, u);
          } catch (Throwable ex) {
              throw ExceptionHelper.wrapOrThrow(ex);
          }
      }
  
      /**
       * Wraps the call to the Scheduler creation callable in try-catch and propagates thrown
       * checked exceptions as RuntimeException and enforces that result is not null.
       * @param s the {@link Callable} which returns a {@link Scheduler}, not null (not verified). Cannot return null
       * @return the result of the callable call, not null
       * @throws NullPointerException if the callable parameter returns null
       */
      @NonNull
      static Scheduler callRequireNonNull(@NonNull Callable<Scheduler> s) {
          try {
              return ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can't be null");
          } catch (Throwable ex) {
              throw ExceptionHelper.wrapOrThrow(ex);
          }
      }
  
      /**
       * Wraps the call to the Scheduler creation function in try-catch and propagates thrown
       * checked exceptions as RuntimeException and enforces that result is not null.
       * @param f the function to call, not null (not verified). Cannot return null
       * @param s the parameter value to the function
       * @return the result of the function call, not null
       * @throws NullPointerException if the function parameter returns null
       */
      @NonNull
      static Scheduler applyRequireNonNull(@NonNull Function<? super Callable<Scheduler>, ? extends Scheduler> f, Callable<Scheduler> s) {
          return ObjectHelper.requireNonNull(apply(f, s), "Scheduler Callable result can't be null");
      }
  
      /** Helper class, no instances. */
      private RxJavaObservablePlugins() {
          throw new IllegalStateException("No instances!");
      }
  }
  