How to Wrap a Stream

The reverse method contains some other interesting code;
in particular, these two statements:

BufferedReader in = new BufferedReader(source);
...
PrintWriter out = new PrintWriter(pipeOut);

The code opens a BufferedReader on source,
which is another reader of a different type.
This essentially "wraps" source in a
BufferedReader.
The program reads from the BufferedReader,
which in turn reads from source.
The program does this so that it can use
BufferedReader's convenient readLine method.
Similarly, the PipedWriter
is wrapped in a PrintWriter
so that the program can use PrintWriter's
convenient println method.
You will often see streams wrapped in this
way so as to combine the various features of the many streams.