code: public CompletableFuture<ResultType> process(ItemType item) {
          Preconditions.checkNotNull(item, "item");
          CompletableFuture<ResultType> result = null;
          synchronized (this.stateLock) {
              Exceptions.checkNotClosed(this.closed, this);
              if (hasCapacity() && this.pendingItems.isEmpty()) {
                  // Not at capacity. Reserve a spot now.
                  this.activeCount++;
              } else {
                  // We are at capacity or have a backlog. Put the item in the queue and return its associated future.
                  result = new CompletableFuture<>();
                  this.pendingItems.add(new QueueItem(item, result));
              }
          }
  
          if (result == null) {
              // We are below max capacity, so simply process the item, without queuing up.
              // It is possible, under some conditions, that we may get in here when the queue empties up (by two spots at
              // the same time). In that case, we need to acquire the processing lock to ensure that we don't accidentally
              // process this item before we finish processing the last item in the queue.
              synchronized (this.processingLock) {
                  result = processInternal(item);
              }
          }
  
          return result;
      }
docs: Processes the given item.
  * If the OrderedItemProcessor is below capacity, then the item will be processed immediately and the returned
  future is the actual result from the Processor.
  * If the max capacity is exceeded, the item will be queued up and it will be processed when capacity allows, after
  all the items added before it have been processed.
  * If an item before this one failed to process and this item is still in the queue (it has not yet been processed),
  the returned future will be cancelled with a ProcessingException to prevent out-of-order executions.
  * This method guarantees ordered execution as long as its invocations are serial. That is, it only guarantees that
  the item has begun processing or an order assigned if the method returned successfully.
  * If an item failed to execute, this class will auto-close and will not be usable anymore.
  
  @param item The item to process.
  @return A CompletableFuture that, when completed, will indicate that the item has been processed. This will contain
  the result of the processing function applied to this item.