class IgniteThinClientCasBasedProxyManager<K> extends AbstractCompareAndSwapBasedProxyManager<K> {

    private final ClientCache<K, ByteBuffer> cache;

    public IgniteThinClientCasBasedProxyManager(ClientCache<K, ByteBuffer> cache) {
        this(cache, ClientSideConfig.getDefault());
    }

    public IgniteThinClientCasBasedProxyManager(ClientCache<K, ByteBuffer> cache, ClientSideConfig clientSideConfig) {
        super(clientSideConfig);
        this.cache = Objects.requireNonNull(cache);
    }

    @Override
    protected CompareAndSwapOperation beginCompareAndSwapOperation(K key) {
        return new CompareAndSwapOperation() {
            @Override
            public Optional<byte[]> getStateData(Optional<Long> timeoutNanos) {
                ByteBuffer persistedState = cache.get(key);
                if (persistedState == null) {
                    return Optional.empty();
                }
                byte[] persistedStateBytes = persistedState.array();
                return Optional.of(persistedStateBytes);
            }
            @Override
            public boolean compareAndSwap(byte[] originalDataBytes, byte[] newDataBytes, RemoteBucketState newState, Optional<Long> timeoutNanos) {
                ByteBuffer newData = ByteBuffer.wrap(newDataBytes);
                if (originalDataBytes == null) {
                    return cache.putIfAbsent(key, newData);
                }
                ByteBuffer originalData = ByteBuffer.wrap(originalDataBytes);
                return cache.replace(key, originalData, newData);
            }
        };
    }

    @Override
    protected AsyncCompareAndSwapOperation beginAsyncCompareAndSwapOperation(K key) {<FILL_FUNCTION_BODY>}

    @Override
    public boolean isAsyncModeSupported() {
        return true;
    }

    @Override
    public void removeProxy(K key) {
        cache.remove(key);
    }

    @Override
    protected CompletableFuture<Void> removeAsync(K key) {
        IgniteClientFuture<Boolean> igniteFuture = cache.removeAsync(key);
        return ThinClientUtils.convertFuture(igniteFuture).thenApply(result -> null);
    }

}

        return new AsyncCompareAndSwapOperation() {
            @Override
            public CompletableFuture<Optional<byte[]>> getStateData(Optional<Long> timeoutNanos) {
                IgniteClientFuture<ByteBuffer> igniteFuture = cache.getAsync(key);
                CompletableFuture<ByteBuffer> resultFuture = ThinClientUtils.convertFuture(igniteFuture);
                return resultFuture.thenApply((ByteBuffer persistedState) -> {
                    if (persistedState == null) {
                        return Optional.empty();
                    }
                    byte[] persistedStateBytes = persistedState.array();
                    return Optional.of(persistedStateBytes);
                });
            }
            @Override
            public CompletableFuture<Boolean> compareAndSwap(byte[] originalDataBytes, byte[] newDataBytes, RemoteBucketState newState, Optional<Long> timeoutNanos) {
                ByteBuffer newData = ByteBuffer.wrap(newDataBytes);
                if (originalDataBytes == null) {
                    IgniteClientFuture<Boolean> igniteFuture = cache.putIfAbsentAsync(key, newData);
                    return ThinClientUtils.convertFuture(igniteFuture);
                }
                ByteBuffer originalData = ByteBuffer.wrap(originalDataBytes);
                IgniteClientFuture<Boolean> igniteFuture = cache.replaceAsync(key, originalData, newData);
                return ThinClientUtils.convertFuture(igniteFuture);
            }
        };
    
<methods>public CommandResult<T> execute(K, Request<T>) ,public CompletableFuture<CommandResult<T>> executeAsync(K, Request<T>) <variables>private static final CommandResult<?> UNSUCCESSFUL_CAS_RESULT