class LocalCacheService implements LocalCache, Serializable {

    @Override
    public <T> T computeIfAbsent(final Class<T> expectedClass, final String key, final Predicate<Element> toRemove,
            final long timeoutMs, final Supplier<T> value) {

        final Integer maxSize = this.getConfigValue(CacheConfiguration::getDefaultMaxSize, -1);
        if (maxSize > 0 && this.cache.size() >= maxSize) {
            this.clean(); // clean before add one element.
            if (this.cache.size() >= maxSize) {
                synchronized (this.cache) {
                    while (this.cache.size() >= maxSize) {
                        final String keyToRemove = this.cache.keySet().iterator().next();
                        this.cache.remove(keyToRemove);
                    }
                }
            }
        }

        final ScheduledFuture<?> task = timeoutMs > 0 ? this.evictionTask(key, timeoutMs) : null;

        final long endOfValidity = this.calcEndOfValidity(timeoutMs);
        final ElementImpl element =
                this.addToMap(key, () -> new ElementImpl(value, toRemove, endOfValidity, task, this.timer));

        return element.getValue(expectedClass);
    }

    public  LocalCacheService(final String plugin, final Supplier<Long> timer,
            final Supplier<ScheduledExecutorService> threadServiceGetter);

}