/**
   * Will lookup and get the configured {@link java.util.concurrent.ExecutorService} from the given
   * definition.
   *
   * <p>This method will lookup for configured thread pool in the following order
   *
   * <ul>
   *   <li>from the definition if any explicit configured executor service.
   *   <li>from the {@link org.apache.camel.spi.Registry} if found
   *   <li>from the known list of {@link org.apache.camel.spi.ThreadPoolProfile
   *       ThreadPoolProfile(s)}.
   *   <li>if none found, then <tt>null</tt> is returned.
   * </ul>
   *
   * The various {@link ExecutorServiceAwareDefinition} should use this helper method to ensure they
   * support configured executor services in the same coherent way.
   *
   * @param routeContext the route context
   * @param name name which is appended to the thread name, when the {@link
   *     java.util.concurrent.ExecutorService} is created based on a {@link
   *     org.apache.camel.spi.ThreadPoolProfile}.
   * @param definition the node definition which may leverage executor service.
   * @param useDefault whether to fallback and use a default thread pool, if no explicit configured
   * @return the configured executor service, or <tt>null</tt> if none was configured.
   * @throws IllegalArgumentException is thrown if lookup of executor service in {@link
   *     org.apache.camel.spi.Registry} was not found
   */
  public static ExecutorService getConfiguredExecutorService(
      RouteContext routeContext,
      String name,
      ExecutorServiceAwareDefinition<?> definition,
      boolean useDefault)
      throws IllegalArgumentException {
    ExecutorServiceManager manager = routeContext.getCamelContext().getExecutorServiceManager();
    ObjectHelper.notNull(manager, "ExecutorServiceManager", routeContext.getCamelContext());

    // prefer to use explicit configured executor on the definition
    if (definition.getExecutorService() != null) {
      return definition.getExecutorService();
    } else if (definition.getExecutorServiceRef() != null) {
      // lookup in registry first and use existing thread pool if exists
      ExecutorService answer =
          lookupExecutorServiceRef(
              routeContext, name, definition, definition.getExecutorServiceRef());
      if (answer == null) {
        throw new IllegalArgumentException(
            "ExecutorServiceRef "
                + definition.getExecutorServiceRef()
                + " not found in registry or as a thread pool profile.");
      }
      return answer;
    } else if (useDefault) {
      return manager.newDefaultThreadPool(definition, name);
    }

    return null;
  }
  /**
   * Will lookup in {@link org.apache.camel.spi.Registry} for a {@link ScheduledExecutorService}
   * registered with the given <tt>executorServiceRef</tt> name.
   *
   * <p>This method will lookup for configured thread pool in the following order
   *
   * <ul>
   *   <li>from the {@link org.apache.camel.spi.Registry} if found
   *   <li>from the known list of {@link org.apache.camel.spi.ThreadPoolProfile
   *       ThreadPoolProfile(s)}.
   *   <li>if none found, then <tt>null</tt> is returned.
   * </ul>
   *
   * @param routeContext the route context
   * @param name name which is appended to the thread name, when the {@link
   *     java.util.concurrent.ExecutorService} is created based on a {@link
   *     org.apache.camel.spi.ThreadPoolProfile}.
   * @param source the source to use the thread pool
   * @param executorServiceRef reference name of the thread pool
   * @return the executor service, or <tt>null</tt> if none was found.
   */
  public static ScheduledExecutorService lookupScheduledExecutorServiceRef(
      RouteContext routeContext, String name, Object source, String executorServiceRef) {

    ExecutorServiceManager manager = routeContext.getCamelContext().getExecutorServiceManager();
    ObjectHelper.notNull(manager, "ExecutorServiceManager", routeContext.getCamelContext());
    ObjectHelper.notNull(executorServiceRef, "executorServiceRef");

    // lookup in registry first and use existing thread pool if exists
    ScheduledExecutorService answer =
        routeContext
            .getCamelContext()
            .getRegistry()
            .lookupByNameAndType(executorServiceRef, ScheduledExecutorService.class);
    if (answer == null) {
      // then create a thread pool assuming the ref is a thread pool profile id
      answer = manager.newScheduledThreadPool(source, name, executorServiceRef);
    }
    return answer;
  }