@Test
public void testThreadedLeaseIncrease() throws Exception
{

    final Timing timing = new Timing();
    CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), timing.session(), timing.connection(), new RetryOneTime(1));
    try
    {
        client.start();
        final SharedCount count = new SharedCount(client, "/foo/count", 1);
        count.start();
        final InterProcessSemaphoreV2 semaphore = new InterProcessSemaphoreV2(client, "/test", count);
        ExecutorService service = Executors.newCachedThreadPool();
        final CountDownLatch latch1 = new CountDownLatch(1);
        final CountDownLatch latch2 = new CountDownLatch(1);
        Future<Object> future1 = service.submit
            (
                new Callable<Object>()
                {
                    @Override
                    public Object call() throws Exception
                    {
                        Lease lease = semaphore.acquire(timing.seconds(), TimeUnit.SECONDS);
                        Assert.assertNotNull(lease);
                        latch1.countDown();
                        lease = semaphore.acquire(timing.forWaiting().seconds(), TimeUnit.SECONDS);
                        Assert.assertNotNull(lease);
                        latch2.countDown();
                        return null;
                    }
                }
            );
        Future<Object> future2 = service.submit
            (
                new Callable<Object>()
                {
                    @Override
                    public Object call() throws Exception
                    {
                        Assert.assertTrue(latch1.await(timing.forWaiting().seconds(), TimeUnit.SECONDS));
                        timing.sleepABit(); // make sure second acquire is waiting
                        Assert.assertTrue(count.trySetCount(2));
                        //Make sure second acquire takes less than full waiting time:
                        timing.sleepABit();
                        Assert.assertTrue(latch2.await(0, TimeUnit.SECONDS));
                        return null;
                    }
                }
            );
        future1.get();
        future2.get();
        count.close();
    }
    finally
    {
        TestCleanState.closeAndTestClean(client);
    }
}