package com.github.rvesse.airline.io.output;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("rawtypes")
public abstract class ControlOutputStream extends FilterOutputStream {

    private final List<OutputStreamControlTracker> controls = new ArrayList<OutputStreamControlTracker>();
    
    public ControlOutputStream(OutputStream output) {
        super(output);
    }
    
    protected final void registerControl(OutputStreamControlTracker control) {
        this.controls.add(control);
    }

    @Override
    public void write(int b) throws IOException {
        this.applyAll();
        super.write(b);
    }

    @Override
    public void write(byte[] b) throws IOException {
        this.applyAll();
        super.write(b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        this.applyAll();
        super.write(b, off, len);
    }
    
    protected final void applyAll() throws IOException {
        for (OutputStreamControlTracker control : this.controls) {
            control.apply();
        }
    }

    @Override
    public void close() throws IOException {
        resetAll();
        super.close();
    }

    protected final void resetAll() throws IOException {
        for (OutputStreamControlTracker control : this.controls) {
            control.reset();
        }
    }
}

@@ -393,24 +393,94 @@
 er%3E();%0A    %0A
+    private static final byte%5B%5D NEWLINE_BYTES = %22%5Cn%22.getBytes();%0A    %0A
     public C
@@ -1523,10 +1523,259 @@
 %7D%0A    %7D%0A
+    %0A    public void print(String value) throws IOException %7B%0A        this.write(value.getBytes());%0A    %7D%0A    %0A    public void println(String value) throws IOException %7B%0A        this.write(value.getBytes());%0A        this.write(NEWLINE_BYTES);%0A    %7D%0A
 %7D%0A

Add useful print() and println() methods to ControlOutputStream (#18)