// Path: tomitribe-crest-api/src/main/java/org/tomitribe/crest/api/PrintOutput.java
// public interface PrintOutput {
//     public void write(final PrintStream os) throws IOException;
// }
// 
// Path: tomitribe-crest/src/main/java/org/tomitribe/crest/cmds/CommandFailedException.java
// public class CommandFailedException extends RuntimeException {
// 
//     private final String name;
// 
//     public CommandFailedException(Throwable cause, String name) {
//         super(cause);
//         this.name = name;
//     }
// 
//     public String getName() {
//         return name;
//     }
// }
// 
// Path: tomitribe-crest-test/src/main/java/org/tomitribe/crest/test/Java.java
// public class Java {
//     private Java() {
//     }
// 
//     public static Result java(final String... args) {
//         try {
//             final ProcessBuilder java = javaProcess();
//             java.command().addAll(Arrays.asList(args));
//             return new Result(java.start());
//         } catch (InterruptedException | ExecutionException | IOException e) {
//             throw new IllegalStateException(e);
//         }
//     }
// 
//     private static ProcessBuilder javaProcess() {
//         final File javaHome = new File(System.getenv("JAVA_HOME"));
//         File java = new File(new File(javaHome, "bin"), "java");
// 
//         if (!java.exists()) {
//             java = new File(new File(javaHome, "bin"), "java.exe");
//         }
// 
//         if (!java.exists()) throw new IllegalStateException("No java executable found");
//         if (!java.canExecute()) throw new IllegalStateException("Not executable: " + java.getAbsolutePath());
// 
//         final ProcessBuilder builder = new ProcessBuilder();
//         final List<String> command = builder.command();
//         command.add(java.getAbsolutePath());
//         return builder;
//     }
// 
//     public static class Result {
//         private final String out;
//         private final String err;
//         private final int exitCode;
// 
//         public Result(final Process process) throws InterruptedException, ExecutionException {
//             final Future<Pipe> stout = Pipe.pipe(process.getInputStream(), System.out);
//             final Future<Pipe> sterr = Pipe.pipe(process.getErrorStream(), System.err);
// 
//             this.exitCode = process.waitFor();
//             this.out = stout.get().asString();
//             this.err = sterr.get().asString();
//         }
// 
//         public String getOut() {
//             return out;
//         }
// 
//         public String getErr() {
//             return err;
//         }
// 
//         public int getExitCode() {
//             return exitCode;
//         }
//     }
// 
//     public static final class Pipe implements Runnable {
// 
//         private final InputStream in;
//         private final ByteArrayOutputStream out = new ByteArrayOutputStream();
//         private final OutputStream[] cc;
// 
//         public Pipe(final InputStream in, final OutputStream... copy) {
//             this.in = in;
//             this.cc = copy;
//         }
// 
//         public static Future<Pipe> pipe(final InputStream in, final OutputStream... copy) {
//             final Pipe target = new Pipe(in, copy);
// 
//             final FutureTask<Pipe> task = new FutureTask<Pipe>(target, target);
//             final Thread thread = new Thread(task);
//             thread.setDaemon(true);
//             thread.start();
// 
//             return task;
//         }
// 
//         public synchronized String asString() {
//             return new String(out.toByteArray());
//         }
// 
//         public synchronized void run() {
//             try {
//                 int i = -1;
// 
//                 final byte[] buf = new byte[1024];
// 
//                 while ((i = in.read(buf)) != -1) {
//                     out.write(buf, 0, i);
//                     for (final OutputStream stream : cc) {
//                         stream.write(buf, 0, i);
//                     }
//                 }
//             } catch (final Exception e) {
//                 e.printStackTrace();
//             }
//         }
//     }
// }


import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.tomitribe.crest.api.Command;
import org.tomitribe.crest.api.Exit;
import org.tomitribe.crest.api.PrintOutput;
import org.tomitribe.crest.api.StreamingOutput;
import org.tomitribe.crest.cmds.CommandFailedException;
import org.tomitribe.crest.test.Java;
import java.lang.reflect.Constructor;
import java.util.Iterator;
import java.util.stream.Stream;
                "java.lang.RuntimeException: No good\n\tat ",
                "\tat org.tomitribe.crest.ExceptionHandlingTest",
                "\tat org.tomitribe.crest.Main.main(Main.java:"
        );
    }

    @Test
    public void testStringError() {
        assertHandlingAndStacktrace("String", Error.class, "Do not compute", 255,
                "java.lang.Error: Do not compute\n\tat ",
                "\tat org.tomitribe.crest.ExceptionHandlingTest",
                "\tat org.tomitribe.crest.Main.main(Main.java:"
        );
    }

    @Test
    public void testStringLovePotionNumberNineException() {
        assertHandling("String", LovePotionNumberNineException.class, "A cop was kissed", 9, "A cop was kissed\n");
    }

    @Test
    public void testStringIShouldHaveKnownBetterException() {
        assertHandlingAndStacktrace("String", IShouldHaveKnownBetterException.class, "Do not compute", 255,
                "org.tomitribe.crest.ExceptionHandlingTest$IShouldHaveKnownBetterException: Do not compute\n\tat ",
                "\tat org.tomitribe.crest.ExceptionHandlingTest",
                "\tat org.tomitribe.crest.Main.main(Main.java:"
        );
    }

    @Test
// Path: tomitribe-crest-api/src/main/java/org/tomitribe/crest/api/PrintOutput.java
// public interface PrintOutput {
//     public void write(final PrintStream os) throws IOException;
// }
// 
// Path: tomitribe-crest/src/main/java/org/tomitribe/crest/cmds/CommandFailedException.java
// public class CommandFailedException extends RuntimeException {
// 
//     private final String name;
// 
//     public CommandFailedException(Throwable cause, String name) {
//         super(cause);
//         this.name = name;
//     }
// 
//     public String getName() {
//         return name;
//     }
// }
// 
// Path: tomitribe-crest-test/src/main/java/org/tomitribe/crest/test/Java.java
// public class Java {
//     private Java() {
//     }
// 
//     public static Result java(final String... args) {
//         try {
//             final ProcessBuilder java = javaProcess();
//             java.command().addAll(Arrays.asList(args));
//             return new Result(java.start());
//         } catch (InterruptedException | ExecutionException | IOException e) {
//             throw new IllegalStateException(e);
//         }
//     }
// 
//     private static ProcessBuilder javaProcess() {
//         final File javaHome = new File(System.getenv("JAVA_HOME"));
//         File java = new File(new File(javaHome, "bin"), "java");
// 
//         if (!java.exists()) {
//             java = new File(new File(javaHome, "bin"), "java.exe");
//         }
// 
//         if (!java.exists()) throw new IllegalStateException("No java executable found");
//         if (!java.canExecute()) throw new IllegalStateException("Not executable: " + java.getAbsolutePath());
// 
//         final ProcessBuilder builder = new ProcessBuilder();
//         final List<String> command = builder.command();
//         command.add(java.getAbsolutePath());
//         return builder;
//     }
// 
//     public static class Result {
//         private final String out;
//         private final String err;
//         private final int exitCode;
// 
//         public Result(final Process process) throws InterruptedException, ExecutionException {
//             final Future<Pipe> stout = Pipe.pipe(process.getInputStream(), System.out);
//             final Future<Pipe> sterr = Pipe.pipe(process.getErrorStream(), System.err);
// 
//             this.exitCode = process.waitFor();
//             this.out = stout.get().asString();
//             this.err = sterr.get().asString();
//         }
// 
//         public String getOut() {
//             return out;
//         }
// 
//         public String getErr() {
//             return err;
//         }
// 
//         public int getExitCode() {
//             return exitCode;
//         }
//     }
// 
//     public static final class Pipe implements Runnable {
// 
//         private final InputStream in;
//         private final ByteArrayOutputStream out = new ByteArrayOutputStream();
//         private final OutputStream[] cc;
// 
//         public Pipe(final InputStream in, final OutputStream... copy) {
//             this.in = in;
//             this.cc = copy;
//         }
// 
//         public static Future<Pipe> pipe(final InputStream in, final OutputStream... copy) {
//             final Pipe target = new Pipe(in, copy);
// 
//             final FutureTask<Pipe> task = new FutureTask<Pipe>(target, target);
//             final Thread thread = new Thread(task);
//             thread.setDaemon(true);
//             thread.start();
// 
//             return task;
//         }
// 
//         public synchronized String asString() {
//             return new String(out.toByteArray());
//         }
// 
//         public synchronized void run() {
//             try {
//                 int i = -1;
// 
//                 final byte[] buf = new byte[1024];
// 
//                 while ((i = in.read(buf)) != -1) {
//                     out.write(buf, 0, i);
//                     for (final OutputStream stream : cc) {
//                         stream.write(buf, 0, i);
//                     }
//                 }
//             } catch (final Exception e) {
//                 e.printStackTrace();
//             }
//         }
//     }
// }


// Path: tomitribe-crest/src/test/java/org/tomitribe/crest/ExceptionHandlingTest.java
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.tomitribe.crest.api.Command;
import org.tomitribe.crest.api.Exit;
import org.tomitribe.crest.api.PrintOutput;
import org.tomitribe.crest.api.StreamingOutput;
import org.tomitribe.crest.cmds.CommandFailedException;
import org.tomitribe.crest.test.Java;
import java.lang.reflect.Constructor;
import java.util.Iterator;
import java.util.stream.Stream;

                "java.lang.RuntimeException: No good\n\tat ",
                "\tat org.tomitribe.crest.ExceptionHandlingTest",
                "\tat org.tomitribe.crest.Main.main(Main.java:"
        );
    }

    @Test
    public void testStringError() {
        assertHandlingAndStacktrace("String", Error.class, "Do not compute", 255,
                "java.lang.Error: Do not compute\n\tat ",
                "\tat org.tomitribe.crest.ExceptionHandlingTest",
                "\tat org.tomitribe.crest.Main.main(Main.java:"
        );
    }

    @Test
    public void testStringLovePotionNumberNineException() {
        assertHandling("String", LovePotionNumberNineException.class, "A cop was kissed", 9, "A cop was kissed\n");
    }

    @Test
    public void testStringIShouldHaveKnownBetterException() {
        assertHandlingAndStacktrace("String", IShouldHaveKnownBetterException.class, "Do not compute", 255,
                "org.tomitribe.crest.ExceptionHandlingTest$IShouldHaveKnownBetterException: Do not compute\n\tat ",
                "\tat org.tomitribe.crest.ExceptionHandlingTest",
                "\tat org.tomitribe.crest.Main.main(Main.java:"
        );
    }

    @Test
    public void testStringPleadTheFifthException() {