/** {@inheritDoc} */
  public void reverse(int from, int to) {
    if (from > to) throw new IllegalArgumentException("from > to : " + from + ">" + to);

    TFloatLink start = getLinkAt(from);
    TFloatLink stop = getLinkAt(to);
    TFloatLink prev, next;
    TFloatLink tmp = null;

    TFloatLink tmpHead = start.getPrevious();

    //
    TFloatLink l = start;
    while (l != stop) {
      next = l.getNext();
      prev = l.getPrevious();
      //
      tmp = l;
      l = l.getNext();
      //
      tmp.setNext(prev);
      tmp.setPrevious(next);
    }

    // At this point l == stop and tmp is the but last element {
    if (got(tmp)) {
      tmpHead.setNext(tmp);
      stop.setPrevious(tmpHead);
    }
    start.setNext(stop);
    stop.setPrevious(start);
  }
  /**
   * unlinks the give TFloatLink from the list
   *
   * @param l
   */
  private void removeLink(TFloatLink l) {
    if (no(l)) return;

    size--;

    TFloatLink prev = l.getPrevious();
    TFloatLink next = l.getNext();

    if (got(prev)) {
      prev.setNext(next);
    } else {
      // No previous we must be head
      head = next;
    }

    if (got(next)) {
      next.setPrevious(prev);
    } else {
      // No next so me must be tail
      tail = prev;
    }
    // Unlink
    l.setNext(null);
    l.setPrevious(null);
  }
  /**
   * Returns link at given absolute offset starting from link 'l' at index 'idx'
   *
   * @param l
   * @param idx
   * @param offset
   * @param next
   * @return
   */
  private static TFloatLink getLink(TFloatLink l, int idx, int offset, boolean next) {
    int i = idx;
    //
    while (got(l)) {
      if (i == offset) {
        return l;
      }

      i = i + (next ? 1 : -1);
      l = next ? l.getNext() : l.getPrevious();
    }

    return null;
  }
  void insert(int offset, TFloatLinkedList tmp) {
    TFloatLink l = getLinkAt(offset);

    size = size + tmp.size;
    //
    if (l == head) {
      // Add in front
      tmp.tail.setNext(head);
      head.setPrevious(tmp.tail);
      head = tmp.head;

      return;
    }

    if (no(l)) {
      if (size == 0) {
        // New empty list
        head = tmp.head;
        tail = tmp.tail;
      } else {
        // append
        tail.setNext(tmp.head);
        tmp.head.setPrevious(tail);
        tail = tmp.tail;
      }
    } else {
      TFloatLink prev = l.getPrevious();
      l.getPrevious().setNext(tmp.head);

      // Link by behind tmp
      tmp.tail.setNext(l);
      l.setPrevious(tmp.tail);

      tmp.head.setPrevious(prev);
    }
  }
  /** {@inheritDoc} */
  public void reverse() {
    TFloatLink h = head;
    TFloatLink t = tail;
    TFloatLink prev, next, tmp;

    //
    TFloatLink l = head;
    while (got(l)) {
      next = l.getNext();
      prev = l.getPrevious();
      //
      tmp = l;
      l = l.getNext();
      //
      tmp.setNext(prev);
      tmp.setPrevious(next);
    }

    //
    head = t;
    tail = h;
  }
 /** {@inheritDoc} */
 public boolean forEachDescending(TFloatProcedure procedure) {
   for (TFloatLink l = tail; got(l); l = l.getPrevious()) {
     if (!procedure.execute(l.getValue())) return false;
   }
   return true;
 }