private void growAndUnwrap(int reserveAtStart) {
    if (reserveAtStart < 0) throw new IllegalArgumentException("illegal argument: "+reserveAtStart);
    int oldCapacity = myQueue.length;
    int newCapacity = reserveAtStart + (oldCapacity < 100_000 ? oldCapacity * 2 : oldCapacity + (oldCapacity >> 1)); // overflow aware
    if (newCapacity <= oldCapacity + reserveAtStart) {
      throw new OutOfMemoryError("reserveAtStart: "+reserveAtStart+"; oldCapacity: "+oldCapacity);
    }
    Object[] newQueue = new Object[newCapacity];
    int firstChunkSize;
    if (head <= tail) {
      firstChunkSize = tail - head;
    }
    else {
      firstChunkSize = oldCapacity - head;
      System.arraycopy(myQueue, 0, newQueue, reserveAtStart + firstChunkSize, tail);
    }
    System.arraycopy(myQueue, head, newQueue, reserveAtStart, firstChunkSize);
    tail = size() + reserveAtStart;
    head = reserveAtStart;
    myQueue = newQueue;
  }
private void growAndUnwrap(int reserveAtStart)