/**
   * Offer two elements at the same time.
   *
   * <p>Don't use the regular offer() with this at all!
   *
   * @param first
   * @param second
   * @return
   */
  public boolean offer(T first, T second) {
    final AtomicReferenceArray<Object> buffer = producerBuffer;
    final long p = producerIndex;
    final int m = producerMask;

    int pi = calcWrappedOffset(p + 2, m);

    if (null == lvElement(buffer, pi)) {
      pi = calcWrappedOffset(p, m);
      soElement(buffer, pi + 1, second);
      soProducerIndex(p + 2);
      soElement(buffer, pi, first);
    } else {
      final int capacity = buffer.length();
      final AtomicReferenceArray<Object> newBuffer = new AtomicReferenceArray<>(capacity);
      producerBuffer = newBuffer;

      pi = calcWrappedOffset(p, m);
      soElement(newBuffer, pi + 1, second); // StoreStore
      soElement(newBuffer, pi, first);
      soNext(buffer, newBuffer);

      soProducerIndex(p + 2); // this ensures correctness on 32bit platforms

      soElement(buffer, pi, HAS_NEXT); // new buffer is visible after element is
    }

    return true;
  }
 private void resize(
     final AtomicReferenceArray<Object> oldBuffer,
     final long currIndex,
     final int offset,
     final T e,
     final long mask) {
   final int capacity = oldBuffer.length();
   final AtomicReferenceArray<Object> newBuffer = new AtomicReferenceArray<>(capacity);
   producerBuffer = newBuffer;
   producerLookAhead = currIndex + mask - 1;
   soProducerIndex(currIndex + 1); // this ensures correctness on 32bit platforms
   soElement(newBuffer, offset, e); // StoreStore
   soNext(oldBuffer, newBuffer);
   soElement(oldBuffer, offset, HAS_NEXT); // new buffer is visible after element is
   // inserted
 }
 private static final <E> Object lvElement(AtomicReferenceArray<Object> buffer, int offset) {
   return buffer.get(offset);
 }
 private static final void soElement(AtomicReferenceArray<Object> buffer, int offset, Object e) {
   buffer.lazySet(offset, e);
 }
 @SuppressWarnings("unchecked")
 private AtomicReferenceArray<Object> lvNext(AtomicReferenceArray<Object> curr) {
   return (AtomicReferenceArray<Object>) lvElement(curr, calcDirectOffset(curr.length() - 1));
 }
 private void soNext(AtomicReferenceArray<Object> curr, AtomicReferenceArray<Object> next) {
   soElement(curr, calcDirectOffset(curr.length() - 1), next);
 }