class Fabric8DiscoveryServicesAdapter implements Function<KubernetesClient, List<Service>> {

	private static final LogAccessor LOG = new LogAccessor(LogFactory.getLog(Fabric8DiscoveryServicesAdapter.class));

	private static final SpelExpressionParser PARSER = new SpelExpressionParser();

	private static final SimpleEvaluationContext EVALUATION_CONTEXT = SimpleEvaluationContext.forReadOnlyDataBinding()
			.withInstanceMethods().build();

	private final KubernetesClientServicesFunction function;

	private final KubernetesDiscoveryProperties properties;

	private final Predicate<Service> filter;

	Fabric8DiscoveryServicesAdapter(KubernetesClientServicesFunction function, KubernetesDiscoveryProperties properties,
			Predicate<Service> filter) {
		this.function = function;
		this.properties = properties;
		if (filter == null) {
			this.filter = filter();
		}
		else {
			this.filter = filter;
		}
	}

	@Override
	public List<Service> apply(KubernetesClient client) {
		if (!properties.namespaces().isEmpty()) {
			LOG.debug(() -> "searching in namespaces : " + properties.namespaces() + " with filter : "
					+ properties.filter());
			List<Service> services = new ArrayList<>();
			properties.namespaces().forEach(namespace -> services.addAll(client.services().inNamespace(namespace)
					.withLabels(properties.serviceLabels()).list().getItems().stream().filter(filter).toList()));
			return services;
		}
		return function.apply(client).list().getItems().stream().filter(filter).toList();
	}

	Predicate<Service> filter() {<FILL_FUNCTION_BODY>}

}

		String spelExpression = properties.filter();
		Predicate<Service> predicate;
		if (spelExpression == null || spelExpression.isEmpty()) {
			predicate = service -> true;
		}
		else {
			Expression filterExpr = PARSER.parseExpression(spelExpression);
			predicate = service -> {
				Boolean include = filterExpr.getValue(EVALUATION_CONTEXT, service, Boolean.class);
				return Optional.ofNullable(include).orElse(false);
			};
		}
		return predicate;
	
<no_super_class>