package emergencylanding.k.library.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Arrays;

public class MethodizedSTDStream extends ByteArrayOutputStream {
    PrintStream orig = null;
    static String sep = System.getProperty("line.seperator", "\n");

    public MethodizedSTDStream(PrintStream out) {
	orig = out;
    }

    @Override
    public synchronized void write(byte[] b, int off, int len) {
	byte[] aba = Arrays.copyOfRange(b, off, len);
	if (new String(aba).endsWith(sep)) {
	    orig.println();
	    return;
	}
	StackTraceElement[] ste = new Throwable().getStackTrace();

	// use 1 to skip over our entry, and also keep var after loop
	int i = 1;
	StackTraceElement s = null;
	for (; i < ste.length; i++) {
	    s = ste[i];
	    if (!s.getClassName().matches("^(java|sun)(.+?)")) {
		break;
	    }
	}
	if (s == null) {
	    // there is no stack!
	    throw new IllegalStateException("No stack!");
	}
	String[] classsplit = s.getClassName().split("\\.");

	String method = "[" + classsplit[classsplit.length - 1] + "."
		+ s.getMethodName() + "()] ";

	orig.write((method + new String(b)).getBytes(), off,
		len + method.getBytes().length);
    }

    @Override
    public void flush() throws IOException {
	orig.flush();
	reset();
    }

}

@@ -249,16 +249,52 @@
 = null;%0A
+    private boolean nextWriteIsOff;%0A
     stat
@@ -353,16 +353,16 @@
  %22%5Cn%22);%0A
-
 %0A    pub
@@ -788,16 +788,21 @@
 s = null
+, sm1
 ;%0A%09for (
@@ -965,16 +965,16 @@
  stack!%0A
-
 %09    thr
@@ -1019,16 +1019,272 @@
 !%22);%0A%09%7D%0A
+%09sm1 = ste%5Bi - 1%5D;%0A%09if (sm1.getClassName().equals(PrintStream.class.getName())%0A%09%09&& sm1.getMethodName().equals(%22print%22)) %7B%0A%09    nextWriteIsOff = true;%0A%09%7D else if (nextWriteIsOff) %7B%0A%09    orig.write(b, off, len);%0A%09    nextWriteIsOff = false;%0A%09    return;%0A%09%7D%0A
 %09String%5B

Support print()