/**
* Public interface for generic LRStruct<T>.
*/
public class LRStruct<E> {
    private ANode<E> _head;

    public LRStruct() {
       _head = new EmptyNode<E>();
    }

    public String toString() {
        return _head.toString(this);
    }

    public final LRStruct<E> insertFront(E dat) {
        return _head.insertFront(dat, this);
    }

    public final E removeFront() {
        return _head.removeFront(this);
    }

    public final E getFirst() {
        return _head.getFirst (this);
    }

    public final LRStruct<E> setFirst(E dat) {
        return _head.setFirst (dat, this);
    }

    public final LRStruct<E> getRest() {
        return _head.getRest(this);
    }

    public final LRStruct<E> setRest(LRStruct<E> tail) {
        return _head.setRest(tail, this);
    }

    public final <R, P> R execute(IAlgo<? super E, R, P> algo, P ... inp) {
        return _head.execute(this, algo, inp); 
    }

    /* Package access only: */
  
    LRStruct(ANode<E> node) {
        _head = node;
    }

    final LRStruct<E> setHead (ANode<E> head) {
        _head = head;
        return this;
    }

    final ANode<E> getHead () {
        return _head;
    }
}

/*
*  Visitor Interface
*/
public interface IAlgo<E, R, P> {

    public abstract R emptyCase(LRStruct<? extends E> host, P... inp);

    public abstract R nonEmptyCase(LRStruct<? extends E> host, P... inp);
}