class CDSShardAccessImpl implements CDSShardAccess, LeaderLocationListener, AutoCloseable {

    @Override
    public CompletionStage<Void> makeLeaderLocal() {
        // TODO when we have running make leader local operation
        // we should just return the same completion stage
        checkNotClosed();

        // TODO can we cache local shard actorRef?
        final Future<ActorRef> localShardReply =
                actorUtils.findLocalShardAsync(ClusterUtils.getCleanShardName(prefix.getRootIdentifier()));

        // we have to tell local shard to make leader local
        final scala.concurrent.Promise<Object> makeLeaderLocalAsk = Futures.promise();
        localShardReply.onComplete(new OnComplete<ActorRef>() {
            @Override
            public void onComplete(final Throwable failure, final ActorRef actorRef) {
                if (failure instanceof LocalShardNotFoundException) {
                    LOG.debug("No local shard found for {} - Cannot request leadership transfer to local shard.",
                            getShardIdentifier(), failure);
                    makeLeaderLocalAsk.failure(failure);
                } else if (failure != null) {
                    // TODO should this be WARN?
                    LOG.debug("Failed to find local shard for {} - Cannot request leadership transfer to local shard.",
                            getShardIdentifier(), failure);
                    makeLeaderLocalAsk.failure(failure);
                } else {
                    makeLeaderLocalAsk
                            .completeWith(actorUtils
                                    .executeOperationAsync(actorRef, MakeLeaderLocal.INSTANCE, makeLeaderLocalTimeout));
                }
            }
        }, actorUtils.getClientDispatcher());

        // we have to transform make leader local request result
        Future<Void> makeLeaderLocalFuture = makeLeaderLocalAsk.future()
                .transform(new Mapper<Object, Void>() {
                    @Override
                    public Void apply(final Object parameter) {
                        return null;
                    }
                }, new Mapper<Throwable, Throwable>() {
                    @Override
                    public Throwable apply(final Throwable parameter) {
                        if (parameter instanceof LeadershipTransferFailedException) {
                            // do nothing with exception and just pass it as it is
                            return parameter;
                        }
                        // wrap exception in LeadershipTransferFailedEx
                        return new LeadershipTransferFailedException("Leadership transfer failed", parameter);
                    }
                }, actorUtils.getClientDispatcher());

        return FutureConverters.toJava(makeLeaderLocalFuture);
    }

      CDSShardAccessImpl(final DOMDataTreeIdentifier prefix, final ActorUtils actorUtils);

}