@Override
  public int globalWaitingCount(LockID lock) {
    waitUntilRunning();

    int waiterCount = 0;
    for (final ClientServerExchangeLockContext cselc : queryLock(lock)) {
      switch (cselc.getState()) {
        case WAITER:
          waiterCount++;
          break;
          // $CASES-OMITTED$
        default:
          continue;
      }
    }

    if (waiterCount > 0) {
      return waiterCount;
    }

    final ClientLock lockState = getClientLockState(lock);
    if (lockState != null) {
      return lockState.waitingCount();
    } else {
      return 0;
    }
  }
  @Override
  public boolean isLocked(LockID lock, LockLevel level) {
    waitUntilRunning();
    final ClientLock lockState = getClientLockState(lock);
    if (lockState != null) {
      if (lockState.isLocked(level)) {
        return true;
      }
    }

    for (final ClientServerExchangeLockContext cselc : queryLock(lock)) {
      if (this.remoteLockManager.getClientID().equals(cselc.getNodeID())) {
        continue;
      }

      switch (cselc.getState()) {
        case GREEDY_HOLDER_READ:
        case HOLDER_READ:
          if (level == LockLevel.READ) {
            return true;
          }
          break;
        case GREEDY_HOLDER_WRITE:
        case HOLDER_WRITE:
          if ((level == LockLevel.WRITE) || (level == LockLevel.SYNCHRONOUS_WRITE)) {
            return true;
          }
          break;
          // $CASES-OMITTED$
        default:
          continue;
      }
    }
    return false;
  }
  @Override
  public int globalHoldCount(LockID lock, LockLevel level) {
    waitUntilRunning();

    int holdCount = 0;
    final ClientLock lockState = getClientLockState(lock);
    if (lockState != null) {
      holdCount += lockState.holdCount(level);
    }

    for (final ClientServerExchangeLockContext cselc : queryLock(lock)) {
      if (this.remoteLockManager.getClientID().equals(cselc.getNodeID())) {
        continue;
      }

      switch (cselc.getState()) {
        case GREEDY_HOLDER_READ:
        case HOLDER_READ:
          if (level == LockLevel.READ) {
            holdCount++;
          }
          break;
        case GREEDY_HOLDER_WRITE:
          holdCount++;
          break;
        case HOLDER_WRITE:
          if ((level == LockLevel.WRITE) || (level == LockLevel.SYNCHRONOUS_WRITE)) {
            holdCount++;
          }
          break;
          // $CASES-OMITTED$
        default:
          break;
      }
    }

    return holdCount;
  }
  @Override
  public int globalPendingCount(LockID lock) {
    waitUntilRunning();

    int pendingCount = 0;
    final ClientLock lockState = getClientLockState(lock);
    if (lockState != null) {
      pendingCount += lockState.pendingCount();
    }

    for (final ClientServerExchangeLockContext cselc : queryLock(lock)) {
      switch (cselc.getState()) {
        case PENDING_READ:
        case PENDING_WRITE:
          pendingCount++;
          break;
          // $CASES-OMITTED$
        default:
          continue;
      }
    }

    return pendingCount;
  }