// Path: Profiler/src/main/java/net/jproffa/profiler/Output.java
// public class Output<T> {
// 
//     private List<T> input;
//     private List<Integer> size;
//     private List<Long> time;
// 
//     public Output() {
//         input = new ArrayList<T>();
//         size = new ArrayList<Integer>();
//         time = new ArrayList<Long>();
//     }
// 
//     public List<T> getInput() {
//         return input;
//     }
// 
//     public void setInput(List<T> input) {
//         this.input = input;
//     }
// 
//     public List<Integer> getSize() {
//         return size;
//     }
// 
//     public void setSize(List<Integer> size) {
//         this.size = size;
//     }
// 
//     public List<Long> getTime() {
//         return time;
//     }
// 
//     public void setTime(List<Long> time) {
//         this.time = time;
//     }
// 
//     public void addToInput(T object) {
//         input.add(object);
//     }
// 
//     public void addToTime(long t) {
//         time.add(t);
//     }
// 
//     public void addToSize(int i) {
//         size.add(i);
//     }
//     
//     public int entryCount() {
//         return size.size();
//     }
// 
//     @Override
//     public String toString() {
//         if (input.isEmpty()) {
//             return "<empty Output>";
//         }
//         if (input.size() != size.size() || size.size() != time.size()) {
//             return "<invalid Output>";
//         }
//         
//         String[][] rows = new String[][] {
//             new String[input.size()],
//             new String[size.size()],
//             new String[time.size()]
//         };
//         int n = entryCount();
//         for (int col = 0; col < n; ++col) {
//             rows[0][col] = input.get(col).toString();
//             rows[1][col] = size.get(col).toString();
//             rows[2][col] = time.get(col).toString();
//         }
//         
//         return formatTable(rows);
//     }
// 
//     private String formatTable(String[][] rows) {
//         StringBuilder sb = new StringBuilder();
//         int[] colWidths = getColWidths(rows);
//         
//         for (int i = 0; i < rows.length; ++i) {
//             String[] row = rows[i];
//             
//             sb.append("| ");
//             for (int j = 0; j < row.length; ++j) {
//                 if (j > 0) {
//                     sb.append(" | ");
//                 }
//                 
//                 int colWidth = colWidths[j];
//                 int padding = colWidth - row[j].length();
//                 for (int p = 0; p < padding; ++p) {
//                     sb.append(' ');
//                 }
//                 sb.append(row[j]);
//             }
//             sb.append(" |").append("\n");
//         }
//         return sb.toString();
//     }
// 
//     private int[] getColWidths(String[][] rows) {
//         int[] colWidths = new int[entryCount()];
//         for (int j = 0; j < entryCount(); ++j) {
//             int w = 0;
//             for (int i = 0; i < rows.length; ++i) {
//                 w = Math.max(w, rows[i][j].length());
//             }
//             colWidths[j] = w;
//         }
//         return colWidths;
//     }
// 
// }


import com.google.gson.Gson;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import net.jproffa.profiler.Output;
     * GraphRenderer renderer = new GraphRenderer(list);
     * JPanel panel = renderer.getJPanel(); } </pre> 
     * @param time List of times
     * @param input List of inputs
     */
    public void save(List<Long> time, List<Integer> input) throws IOException {
        File file = getFile();
        FileWriter fstream = new FileWriter(file, true);
        BufferedWriter fbw = new BufferedWriter(fstream);
        Gson gson = new Gson();
        String data = gson.toJson(new Line(time, input, className, methodName, annotation));
        fbw.write(data);
        fbw.newLine();
        fbw.close();
    }
    
    /**
     * Saves the output objects time and size lists to file. This data can be read using GraphReader. <p>
     * Example:
     * <pre> {@code @Rule
     * GraphWriter gw = new GraphWriter();
     * Output out = ...;
     * gw.save(out);
     * GraphReader gr = new GraphReader("path/to/directory");
     * List<Line> lines = gr.get("some.TestClass", "testFoo");
     * GraphRenderer renderer = new GraphRenderer(list);
     * JPanel panel = renderer.getJPanel(); } </pre>
     * @param out The output object containing non-empty list of times and list of sizes.
     * @throws IOException 
     */
// Path: Profiler/src/main/java/net/jproffa/profiler/Output.java
// public class Output<T> {
// 
//     private List<T> input;
//     private List<Integer> size;
//     private List<Long> time;
// 
//     public Output() {
//         input = new ArrayList<T>();
//         size = new ArrayList<Integer>();
//         time = new ArrayList<Long>();
//     }
// 
//     public List<T> getInput() {
//         return input;
//     }
// 
//     public void setInput(List<T> input) {
//         this.input = input;
//     }
// 
//     public List<Integer> getSize() {
//         return size;
//     }
// 
//     public void setSize(List<Integer> size) {
//         this.size = size;
//     }
// 
//     public List<Long> getTime() {
//         return time;
//     }
// 
//     public void setTime(List<Long> time) {
//         this.time = time;
//     }
// 
//     public void addToInput(T object) {
//         input.add(object);
//     }
// 
//     public void addToTime(long t) {
//         time.add(t);
//     }
// 
//     public void addToSize(int i) {
//         size.add(i);
//     }
//     
//     public int entryCount() {
//         return size.size();
//     }
// 
//     @Override
//     public String toString() {
//         if (input.isEmpty()) {
//             return "<empty Output>";
//         }
//         if (input.size() != size.size() || size.size() != time.size()) {
//             return "<invalid Output>";
//         }
//         
//         String[][] rows = new String[][] {
//             new String[input.size()],
//             new String[size.size()],
//             new String[time.size()]
//         };
//         int n = entryCount();
//         for (int col = 0; col < n; ++col) {
//             rows[0][col] = input.get(col).toString();
//             rows[1][col] = size.get(col).toString();
//             rows[2][col] = time.get(col).toString();
//         }
//         
//         return formatTable(rows);
//     }
// 
//     private String formatTable(String[][] rows) {
//         StringBuilder sb = new StringBuilder();
//         int[] colWidths = getColWidths(rows);
//         
//         for (int i = 0; i < rows.length; ++i) {
//             String[] row = rows[i];
//             
//             sb.append("| ");
//             for (int j = 0; j < row.length; ++j) {
//                 if (j > 0) {
//                     sb.append(" | ");
//                 }
//                 
//                 int colWidth = colWidths[j];
//                 int padding = colWidth - row[j].length();
//                 for (int p = 0; p < padding; ++p) {
//                     sb.append(' ');
//                 }
//                 sb.append(row[j]);
//             }
//             sb.append(" |").append("\n");
//         }
//         return sb.toString();
//     }
// 
//     private int[] getColWidths(String[][] rows) {
//         int[] colWidths = new int[entryCount()];
//         for (int j = 0; j < entryCount(); ++j) {
//             int w = 0;
//             for (int i = 0; i < rows.length; ++i) {
//                 w = Math.max(w, rows[i][j].length());
//             }
//             colWidths[j] = w;
//         }
//         return colWidths;
//     }
// 
// }


// Path: Graph/src/main/java/net/jproffa/graph/GraphWriter.java
import com.google.gson.Gson;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import net.jproffa.profiler.Output;

     * GraphRenderer renderer = new GraphRenderer(list);
     * JPanel panel = renderer.getJPanel(); } </pre> 
     * @param time List of times
     * @param input List of inputs
     */
    public void save(List<Long> time, List<Integer> input) throws IOException {
        File file = getFile();
        FileWriter fstream = new FileWriter(file, true);
        BufferedWriter fbw = new BufferedWriter(fstream);
        Gson gson = new Gson();
        String data = gson.toJson(new Line(time, input, className, methodName, annotation));
        fbw.write(data);
        fbw.newLine();
        fbw.close();
    }
    
    /**
     * Saves the output objects time and size lists to file. This data can be read using GraphReader. <p>
     * Example:
     * <pre> {@code @Rule
     * GraphWriter gw = new GraphWriter();
     * Output out = ...;
     * gw.save(out);
     * GraphReader gr = new GraphReader("path/to/directory");
     * List<Line> lines = gr.get("some.TestClass", "testFoo");
     * GraphRenderer renderer = new GraphRenderer(list);
     * JPanel panel = renderer.getJPanel(); } </pre>
     * @param out The output object containing non-empty list of times and list of sizes.
     * @throws IOException 
     */
    public void save(Output<?> out) throws IOException {