code: public ListenableFuture<T> getStateChange(T currentState)
      {
          checkState(!Thread.holdsLock(lock), "Can not wait for state change while holding the lock");
          requireNonNull(currentState, "currentState is null");
  
          synchronized (lock) {
              // return a completed future if the state has already changed, or we are in a terminal state
              if (!state.equals(currentState) || isTerminalState(state)) {
                  return immediateFuture(state);
              }
  
              return futureStateChange.get().createNewListener();
          }
      }
docs: Gets a future that completes when the state is no longer {@code .equals()} to {@code currentState)}.