sclass StringHead is Closeable { settable bool readMode; settable bool writeMode; gettable BufferedReader reader; gettable Writer writer; *() {} *(Reader reader) { reader(reader); } *(Writer writer) { writer(writer); } selfType reader(Reader reader) { this.reader = bufferedReader(reader); readMode(true); this; } selfType writer(Writer writer) { this.writer = writer; writeMode(true); this; } void finish {} S readLine() { S line = readLineFromReader(reader); if (line == null) close(); ret line; } void writeLine(S line) ctex { writer.write(line); writer.write('\n'); } void exchangeLine(IF0 getter, IVF1 setter) { if (writeMode()) writeLine(getter!); if (readMode()) setter.get(readLine()); } close { dispose reader; dispose writer; } replace ByteIO with StringIO. void exchange(ByteIO writable) { if (writable != null) writable.readWrite(this); } void exchangeAll(Iterable writables) { if (writables != null) for (writable : writables) exchange(writable); } }