/**
   * Route to the given routing function if the given request predicate applies.
   *
   * @param predicate the predicate to test
   * @param routerFunction the routing function to route to
   * @param <T> the type of the handler function
   * @return a routing function that routes to {@code routerFunction} if {@code predicate} evaluates
   *     to {@code true}
   * @see RequestPredicates
   */
  public static <T> RouterFunction<T> subroute(
      RequestPredicate predicate, RouterFunction<T> routerFunction) {
    Assert.notNull(predicate, "'predicate' must not be null");
    Assert.notNull(routerFunction, "'routerFunction' must not be null");

    return request -> {
      if (predicate.test(request)) {
        ServerRequest subRequest = predicate.subRequest(request);
        return routerFunction.route(subRequest);
      } else {
        return Optional.empty();
      }
    };
  }
  /**
   * Route to the given handler function if the given request predicate applies.
   *
   * @param predicate the predicate to test
   * @param handlerFunction the handler function to route to
   * @param <T> the type of the handler function
   * @return a routing function that routes to {@code handlerFunction} if {@code predicate}
   *     evaluates to {@code true}
   * @see RequestPredicates
   */
  public static <T> RouterFunction<T> route(
      RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
    Assert.notNull(predicate, "'predicate' must not be null");
    Assert.notNull(handlerFunction, "'handlerFunction' must not be null");

    return request -> predicate.test(request) ? Optional.of(handlerFunction) : Optional.empty();
  }