code: ReleaseResult release(SemaphoreEndpoint endpoint, UUID invocationUid, int permits) {
          checkPositive(permits, "Permits should be positive!");
  
          long sessionId = endpoint.sessionId();
          if (sessionId != NO_SESSION_ID) {
              SessionSemaphoreState state = sessionStates.get(sessionId);
              if (state == null) {
                  return ReleaseResult.failed(cancelWaitKeys(endpoint, invocationUid));
              }
  
              if (state.containsInvocation(endpoint.threadId(), invocationUid)) {
                  return ReleaseResult.successful(Collections.<AcquireInvocationKey>emptyList(),
                          Collections.<AcquireInvocationKey>emptyList());
              }
  
              if (state.acquiredPermits < permits) {
                  return ReleaseResult.failed(cancelWaitKeys(endpoint, invocationUid));
              }
  
              state.acquiredPermits -= permits;
              state.invocationRefUids.put(endpoint.threadId(), Tuple2.of(invocationUid, permits));
          }
  
          available += permits;
  
          // order is important...
          Collection<AcquireInvocationKey> cancelled = cancelWaitKeys(endpoint, invocationUid);
          Collection<AcquireInvocationKey> acquired = assignPermitsToWaitKeys();
  
          return ReleaseResult.successful(acquired, cancelled);
      }
docs: Releases the given number of permits.
  Permits are not released if it is a retry of a previous successful
  release request of a session-aware proxy. Permits are released again if
  it is a retry of a successful release request of a sessionless proxy.
  If the release request fails because the requesting endpoint does not
  hold the given number of permits, all wait keys of the endpoint are
  cancelled because that endpoint has stopped waiting for response of
  the previous acquire() invocation. Returns completed wait keys after
  successful release if there are any. Returns cancelled wait keys after
  failed release if there are any.