String attemptLock(long time, TimeUnit unit, byte[] lockNodeBytes) throws Exception {
        final long startMillis = System.currentTimeMillis();
        final Long millisToWait = (unit != null) ? unit.toMillis(time) : null;
        final byte[] localLockNodeBytes = (revocable.get() != null) ? new byte[0] : lockNodeBytes;
        int retryCount = 0;

        String ourPath = null;
        boolean hasTheLock = false;
        boolean isDone = false;
        while (!isDone) {
            isDone = true;

            try {
                ourPath = driver.createsTheLock(client, path, localLockNodeBytes);
                hasTheLock = internalLockLoop(startMillis, millisToWait, ourPath);
            } catch (KeeperException.NoNodeException e) {
                // gets thrown by StandardLockInternalsDriver when it can't find the lock node
                // this can happen when the session expires, etc. So, if the retry allows, just try it all again
                if (client.getZookeeperClient()
                        .getRetryPolicy()
                        .allowRetry(
                                retryCount++,
                                System.currentTimeMillis() - startMillis,
                                RetryLoop.getDefaultRetrySleeper())) {
                    isDone = false;
                } else {
                    throw e;
                }
            }
        }

        if (hasTheLock) {
            return ourPath;
        }

        return null;
    }
@Test
    public void testNodeDeletedCleanlyWithFaults() throws Exception {
        final String PATH = "/foo/bar";

        CuratorFramework client = null;
        try {
            client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryNTimes(0, 0));
            client.start();

            client.create().creatingParentsIfNeeded().forPath(PATH);
            assertEquals(client.checkExists().forPath(PATH).getNumChildren(), 0);

            LockInternals internals = new LockInternals(client, new StandardLockInternalsDriver(), PATH, "lock-", 1) {
                @Override
                List<String> getSortedChildren() throws Exception {
                    throw new KeeperException.NoNodeException();
                }
            };
            try {
                internals.attemptLock(0, null, null);
                fail();
            } catch (KeeperException.NoNodeException dummy) {
                // expected
            }

            // make sure no nodes are left lying around
            assertEquals(client.checkExists().forPath(PATH).getNumChildren(), 0);
        } finally {
            TestCleanState.closeAndTestClean(client);
        }
    }