class LocalCachingProfileCreator extends InitializableObject implements ProfileCreator {

    private ProfileCreator delegate;
    private int cacheSize;
    private int timeout;
    private TimeUnit timeUnit;

    private Store<Credentials, UserProfile> store;

    /**
     * <p>Constructor for LocalCachingProfileCreator.</p>
     */
    public LocalCachingProfileCreator() {}

    /**
     * <p>Constructor for LocalCachingProfileCreator.</p>
     *
     * @param delegate a {@link ProfileCreator} object
     * @param store a {@link Store} object
     */
    public LocalCachingProfileCreator(final ProfileCreator delegate, final Store<Credentials, UserProfile> store) {
        this.delegate = delegate;
        this.store = store;
    }

    /**
     * <p>Constructor for LocalCachingProfileCreator.</p>
     *
     * @param delegate a {@link ProfileCreator} object
     * @param cacheSize a int
     * @param timeout a int
     * @param timeUnit a {@link TimeUnit} object
     */
    public LocalCachingProfileCreator(final ProfileCreator delegate, final int cacheSize,
                                      final int timeout, final TimeUnit timeUnit) {
        this.delegate = delegate;
        this.cacheSize = cacheSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
    }

    /** {@inheritDoc} */
    @Override
    public Optional<UserProfile> create(final CallContext ctx, final Credentials credentials) {<FILL_FUNCTION_BODY>}

    /** {@inheritDoc} */
    @Override
    protected void internalInit(final boolean forceReinit) {
        if (this.store == null) {
            this.store = new GuavaStore<>(cacheSize, timeout, timeUnit);
        }

        if (delegate instanceof InitializableObject initializableObject) {
            initializableObject.init(forceReinit);
        }
    }

    /**
     * <p>removeFromCache.</p>
     *
     * @param credentials a {@link Credentials} object
     */
    public void removeFromCache(final Credentials credentials) {
        this.store.remove(credentials);
    }

    /**
     * <p>isCached.</p>
     *
     * @param credentials a {@link Credentials} object
     * @return a boolean
     */
    public boolean isCached(final Credentials credentials) {
        return this.store.get(credentials).isPresent();
    }
}

        init();

        val optProfile = this.store.get(credentials);
        if (optProfile.isEmpty()) {
            LOGGER.debug("No cached credentials found. Delegating profile creation to {}...", delegate);
            val profile = delegate.create(ctx, credentials);
            if (profile.isPresent()) {
                LOGGER.debug("Caching credential. Using profile {}...", profile.get());
                store.set(credentials, profile.get());
            }
            return profile;
        } else {
            LOGGER.debug("Found cached credential. Using cached profile {}...", optProfile.get());
            return optProfile;
        }
    
<methods>public non-sealed void <init>() ,public int getNbAttempts() ,public void init() ,public void init(boolean) ,public final boolean isInitialized() ,public void reinit() <variables>private java.util.concurrent.atomic.AtomicBoolean initialized,private volatile java.lang.Long lastAttempt,private int maxAttempts,private long minTimeIntervalBetweenAttemptsInMilliseconds,private java.util.concurrent.atomic.AtomicInteger nbAttempts