public class Channel {

    private MVar read;
    private MVar write;

    public Channel () {
	MVar hole = new MVar();
	read = new MVar(hole);
	write = new MVar(hole);
    }

    public Object read () {
	MVar rend = (MVar)read.take();
	ChannelElem item = (ChannelElem)rend.read();
	read.put(item.next());
	return item.value();
    }

    public void write (Object o) {
	MVar newHole = new MVar();
	MVar oldHole = (MVar)write.take();
	oldHole.put(new ChannelElem(o,newHole));
	write.put(newHole);
    }

    public boolean isEmpty () {
	MVar rend = (MVar)read.take();
	boolean b = rend.isEmpty();
	read.put(rend);
	return b;
    }

    public void unGet (Object o) {
        MVar newRend = new MVar();
	MVar rend = (MVar)read.take();
	newRend.put(new ChannelElem (o,rend));
	read.put(newRend);
    }
}
