code: public boolean addAll(int index, Collection<? extends E> c) {
          checkPositionIndex(index);
  
          Object[] a = c.toArray();
          int numNew = a.length;
          if (numNew == 0)
              return false;
  
          Node<E> pred, succ;
          if (index == size) {
              succ = null;
              pred = last;
          } else {
              succ = node(index);
              pred = succ.prev;
          }
  
          for (Object o : a) {
              @SuppressWarnings("unchecked") E e = (E) o;
              Node<E> newNode = new Node<>(pred, e, null);
              if (pred == null)
                  first = newNode;
              else
                  pred.next = newNode;
              pred = newNode;
          }
  
          if (succ == null) {
              last = pred;
          } else {
              pred.next = succ;
              succ.prev = pred;
          }
  
          size += numNew;
          modCount++;
          return true;
      }
docs: Inserts all of the elements in the specified collection into this
  list, starting at the specified position.  Shifts the element
  currently at that position (if any) and any subsequent elements to
  the right (increases their indices).  The new elements will appear
  in the list in the order that they are returned by the
  specified collection's iterator.
  
  @param index index at which to insert the first element
  from the specified collection
  @param c collection containing elements to be added to this list
  @return {@code true} if this list changed as a result of the call
  @throws IndexOutOfBoundsException {@inheritDoc}
  @throws NullPointerException if the specified collection is null