docs: @Override
      public boolean remove(Object o) {
  
          if (o == null) {
              return false;
          }
  
          if (size() == 0) {
              return false;
          }
  
          synchronized (this) {
              //First check the expedited buffer
              synchronized (lock) {
                  //Check if we wrap around the end of the array before iterating
                  if (expeditedPutIndex > expeditedTakeIndex) {
                      for (int i = expeditedTakeIndex; i <= expeditedPutIndex; i++) {
                          if (o.equals(expeditedBuffer[i])) {
                              //Remove element and shift all remaining elements
                              for (int j = i; j < expeditedPutIndex; j++) {
                                  expeditedBuffer[j] = expeditedBuffer[j + 1];
                              }
                              //Null the putIndex
                              expeditedBuffer[expeditedPutIndex] = null;
                              expeditedPutIndex--;
  
                              //Decrement used slots counter
                              numberOfUsedExpeditedSlots.getAndDecrement();
  
                              //TODO if expedited is added for put or offer with timeout add notification here
  
                              return true;
                          }
                      }
                  } else {
                      //We wrap around the array. Loop through in two passes(upper and lower)
                      for (int i = expeditedTakeIndex; i < expeditedBuffer.length; i++) {
                          if (o.equals(expeditedBuffer[i])) {
                              //Remove element and shift all remaining elements up
                              for (int j = i; j > expeditedTakeIndex; j--) {
                                  expeditedBuffer[j] = expeditedBuffer[j - 1];
                              }
                              //Null the putIndex
                              expeditedBuffer[expeditedTakeIndex] = null;
                              if (expeditedTakeIndex == expeditedBuffer.length - 1) {
                                  expeditedTakeIndex = 0;
                              } else {
                                  expeditedTakeIndex++;
                              }
  
                              //Decrement used slots counter
                              numberOfUsedExpeditedSlots.getAndDecrement();
  
                              //TODO if expedited is added for put or offer with timeout add notification here
  
                              return true;
                          }
                      }
                      for (int i = 0; i < expeditedPutIndex; i++) {
                          if (o.equals(expeditedBuffer[i])) {
                              //Remove element and shift all remaining elements down
                              for (int j = i; j < expeditedPutIndex; j++) {
                                  expeditedBuffer[j] = expeditedBuffer[j + 1];
                              }
                              //Null the putIndex
                              expeditedBuffer[expeditedPutIndex] = null;
                              expeditedPutIndex--;
  
                              //Decrement used slots counter
                              numberOfUsedExpeditedSlots.getAndDecrement();
  
                              //TODO if expedited is added for put or offer with timeout add notification here
  
                              return true;
                          }
                      }
                  }
  
                  //Next check the main buffer
                  //Check if we wrap around the end of the array before iterating
                  if (putIndex > takeIndex) {
                      for (int i = takeIndex; i <= putIndex; i++) {
                          if (o.equals(buffer[i])) {
                              //Remove element and shift all remaining elements
                              for (int j = i; j < putIndex; j++) {
                                  buffer[j] = buffer[j + 1];
                              }
                              //Null the putIndex
                              buffer[putIndex] = null;
                              putIndex--;
  
                              //Decrement used slots counter
                              numberOfUsedSlots.getAndDecrement();
  
                              //Notify a waiting put thread that space has cleared
                              notifyPut_();
  
                              return true;
                          }
                      }
                  } else {
                      //We wrap around the array. Loop through in two passes(upper and lower)
                      for (int i = takeIndex; i < buffer.length; i++) {
                          if (o.equals(buffer[i])) {
                              //Remove element and shift all remaining elements up
                              for (int j = i; j > takeIndex; j--) {
                                  buffer[j] = buffer[j - 1];
                              }
                              //Null the putIndex
                              buffer[takeIndex] = null;
                              if (takeIndex == buffer.length - 1) {
                                  takeIndex = 0;
                              } else {
                                  takeIndex++;
                              }
  
                              //Decrement used slots counter
                              numberOfUsedSlots.getAndDecrement();
  
                              //Notify a waiting put thread that space has cleared
                              notifyPut_();
  
                              return true;
                          }
                      }
                      for (int i = 0; i < putIndex; i++) {
                          if (o.equals(buffer[i])) {
                              //Remove element and shift all remaining elements down
                              for (int j = i; j < putIndex; j++) {
                                  buffer[j] = buffer[j + 1];
                              }
                              //Null the putIndex
                              buffer[putIndex] = null;
                              putIndex--;
  
                              //Decrement used slots counter
                              numberOfUsedSlots.getAndDecrement();
  
                              //Notify a waiting put thread that space has cleared
                              notifyPut_();
  
                              return true;
                          }
                      }
                  }
              }
          }
          return false;
      }