// Path: raml-tester-client/src/main/java/guru/nidi/ramlproxy/report/ReportSaver.java
// public class ReportSaver {
//     private final Map<String, List<ReportInfo>> reports = new HashMap<>();
//     private final ReportAggregator aggregator;
// 
//     public ReportSaver() {
//         this(new MultiReportAggregator());
//     }
// 
//     public ReportSaver(ReportAggregator aggregator) {
//         this.aggregator = aggregator;
//     }
// 
//     public final synchronized void addReport(RamlReport report, ServletRamlRequest request, ServletRamlResponse response) {
//         addingReport(report, request, response);
//         aggregator.addReport(report);
//         getOrCreateInfos(report.getRaml().title()).add(new ReportInfo(report, request, response));
//     }
// 
//     public final synchronized void flushReports() {
//         flushingReports(reports.entrySet());
//         reports.clear();
//     }
// 
//     public final void flushUsage() {
//         flushingUsage(aggregator);
//         aggregator.clear();
//     }
// 
//     protected void addingReport(RamlReport report, ServletRamlRequest request, ServletRamlResponse response) {
//     }
// 
//     protected void flushingReports(Iterable<Map.Entry<String, List<ReportInfo>>> reports) {
//     }
// 
//     protected void flushingUsage(ReportAggregator aggregator) {
//     }
// 
//     public synchronized Iterable<Map.Entry<String, List<ReportInfo>>> getReports() {
//         return reports.entrySet();
//     }
// 
//     public synchronized List<ReportInfo> getReports(String context) {
//         return reports.get(context);
//     }
// 
//     public ReportAggregator getAggregator() {
//         return aggregator;
//     }
// 
//     private List<ReportInfo> getOrCreateInfos(String name) {
//         List<ReportInfo> reportList = reports.get(name);
//         if (reportList == null) {
//             reportList = new ArrayList<>();
//             reports.put(name, reportList);
//         }
//         return reportList;
//     }
// 
//     public static class ReportInfo {
//         private final RamlReport report;
//         private final SavableServletRamlRequest request;
//         private final SavableServletRamlResponse response;
// 
//         public ReportInfo(RamlReport report, ServletRamlRequest request, ServletRamlResponse response) {
//             this.report = report;
//             this.request = new SavableServletRamlRequest(request);
//             this.response = new SavableServletRamlResponse(response);
//         }
// 
//         public RamlReport getReport() {
//             return report;
//         }
// 
//         public ServletRamlRequest getRequest() {
//             return request;
//         }
// 
//         public ServletRamlResponse getResponse() {
//             return response;
//         }
//     }
// 
//     private static class SavableServletRamlRequest extends ServletRamlRequest {
//         private final StringBuffer requestURL;
//         private final String queryString;
//         private final Values headerValues;
//         private final String method;
// 
//         public SavableServletRamlRequest(ServletRamlRequest delegate) {
//             super(delegate);
//             requestURL = delegate.getRequestURL();
//             queryString = delegate.getQueryString();
//             headerValues = delegate.getHeaderValues();
//             method = delegate.getMethod();
//         }
// 
//         @Override
//         public StringBuffer getRequestURL() {
//             return requestURL;
//         }
// 
//         @Override
//         public String getQueryString() {
//             return queryString;
//         }
// 
//         @Override
//         public Values getHeaderValues() {
//             return headerValues;
//         }
// 
//         @Override
//         public String getMethod() {
//             return method;
//         }
//     }
// 
//     private static class SavableServletRamlResponse extends ServletRamlResponse {
//         private final byte[] content;
//         private final Values headerValues;
// 
//         public SavableServletRamlResponse(ServletRamlResponse delegate) {
//             super(delegate);
//             content = delegate.getContent();
//             headerValues = delegate.getHeaderValues();
//         }
// 
//         @Override
//         public byte[] getContent() {
//             return content;
//         }
// 
//         @Override
//         public Values getHeaderValues() {
//             return headerValues;
//         }
//     }
// }


import java.io.StringWriter;
import guru.nidi.ramlproxy.report.ReportSaver;
import guru.nidi.ramltester.RamlDefinition;
import guru.nidi.ramltester.core.RamlReport;
import guru.nidi.ramltester.model.internal.RamlApi;
import guru.nidi.ramltester.servlet.ServletRamlRequest;
import guru.nidi.ramltester.servlet.ServletRamlResponse;
import guru.nidi.ramltester.util.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest servletReq = (HttpServletRequest) request;
        final HttpServletResponse servletRes = (HttpServletResponse) response;
        if (!handleCommands(servletReq, servletRes)) {
            final ServletRamlRequest ramlReq = new ServletRamlRequest(servletReq);
            final ServletRamlResponse ramlRes = new ServletRamlResponse(servletRes);
            delay();
            chain.doFilter(ramlReq, ramlRes);
            test(ramlReq, ramlRes);
        }
    }

    @Override
    public void destroy() {
    }

    public void test(ServletRamlRequest request, ServletRamlResponse response) {
        try {
            final RamlReport report = ramlDefinition.testAgainst(request, response);
            saver.addReport(report, request, response);
        } catch (Exception e) {
            try {
                saver.addReport(fromException(ramlDefinition.getRaml(), e), request, response);
            } catch (Exception e2) {
                System.err.println("Problem checking raml '" + ramlDefinition.getRaml().title() + "'");
                e.printStackTrace();
            }
        }
    }

// Path: raml-tester-client/src/main/java/guru/nidi/ramlproxy/report/ReportSaver.java
// public class ReportSaver {
//     private final Map<String, List<ReportInfo>> reports = new HashMap<>();
//     private final ReportAggregator aggregator;
// 
//     public ReportSaver() {
//         this(new MultiReportAggregator());
//     }
// 
//     public ReportSaver(ReportAggregator aggregator) {
//         this.aggregator = aggregator;
//     }
// 
//     public final synchronized void addReport(RamlReport report, ServletRamlRequest request, ServletRamlResponse response) {
//         addingReport(report, request, response);
//         aggregator.addReport(report);
//         getOrCreateInfos(report.getRaml().title()).add(new ReportInfo(report, request, response));
//     }
// 
//     public final synchronized void flushReports() {
//         flushingReports(reports.entrySet());
//         reports.clear();
//     }
// 
//     public final void flushUsage() {
//         flushingUsage(aggregator);
//         aggregator.clear();
//     }
// 
//     protected void addingReport(RamlReport report, ServletRamlRequest request, ServletRamlResponse response) {
//     }
// 
//     protected void flushingReports(Iterable<Map.Entry<String, List<ReportInfo>>> reports) {
//     }
// 
//     protected void flushingUsage(ReportAggregator aggregator) {
//     }
// 
//     public synchronized Iterable<Map.Entry<String, List<ReportInfo>>> getReports() {
//         return reports.entrySet();
//     }
// 
//     public synchronized List<ReportInfo> getReports(String context) {
//         return reports.get(context);
//     }
// 
//     public ReportAggregator getAggregator() {
//         return aggregator;
//     }
// 
//     private List<ReportInfo> getOrCreateInfos(String name) {
//         List<ReportInfo> reportList = reports.get(name);
//         if (reportList == null) {
//             reportList = new ArrayList<>();
//             reports.put(name, reportList);
//         }
//         return reportList;
//     }
// 
//     public static class ReportInfo {
//         private final RamlReport report;
//         private final SavableServletRamlRequest request;
//         private final SavableServletRamlResponse response;
// 
//         public ReportInfo(RamlReport report, ServletRamlRequest request, ServletRamlResponse response) {
//             this.report = report;
//             this.request = new SavableServletRamlRequest(request);
//             this.response = new SavableServletRamlResponse(response);
//         }
// 
//         public RamlReport getReport() {
//             return report;
//         }
// 
//         public ServletRamlRequest getRequest() {
//             return request;
//         }
// 
//         public ServletRamlResponse getResponse() {
//             return response;
//         }
//     }
// 
//     private static class SavableServletRamlRequest extends ServletRamlRequest {
//         private final StringBuffer requestURL;
//         private final String queryString;
//         private final Values headerValues;
//         private final String method;
// 
//         public SavableServletRamlRequest(ServletRamlRequest delegate) {
//             super(delegate);
//             requestURL = delegate.getRequestURL();
//             queryString = delegate.getQueryString();
//             headerValues = delegate.getHeaderValues();
//             method = delegate.getMethod();
//         }
// 
//         @Override
//         public StringBuffer getRequestURL() {
//             return requestURL;
//         }
// 
//         @Override
//         public String getQueryString() {
//             return queryString;
//         }
// 
//         @Override
//         public Values getHeaderValues() {
//             return headerValues;
//         }
// 
//         @Override
//         public String getMethod() {
//             return method;
//         }
//     }
// 
//     private static class SavableServletRamlResponse extends ServletRamlResponse {
//         private final byte[] content;
//         private final Values headerValues;
// 
//         public SavableServletRamlResponse(ServletRamlResponse delegate) {
//             super(delegate);
//             content = delegate.getContent();
//             headerValues = delegate.getHeaderValues();
//         }
// 
//         @Override
//         public byte[] getContent() {
//             return content;
//         }
// 
//         @Override
//         public Values getHeaderValues() {
//             return headerValues;
//         }
//     }
// }


// Path: raml-tester-client/src/main/java/guru/nidi/ramlproxy/core/TesterFilter.java
import java.io.StringWriter;
import guru.nidi.ramlproxy.report.ReportSaver;
import guru.nidi.ramltester.RamlDefinition;
import guru.nidi.ramltester.core.RamlReport;
import guru.nidi.ramltester.model.internal.RamlApi;
import guru.nidi.ramltester.servlet.ServletRamlRequest;
import guru.nidi.ramltester.servlet.ServletRamlResponse;
import guru.nidi.ramltester.util.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest servletReq = (HttpServletRequest) request;
        final HttpServletResponse servletRes = (HttpServletResponse) response;
        if (!handleCommands(servletReq, servletRes)) {
            final ServletRamlRequest ramlReq = new ServletRamlRequest(servletReq);
            final ServletRamlResponse ramlRes = new ServletRamlResponse(servletRes);
            delay();
            chain.doFilter(ramlReq, ramlRes);
            test(ramlReq, ramlRes);
        }
    }

    @Override
    public void destroy() {
    }

    public void test(ServletRamlRequest request, ServletRamlResponse response) {
        try {
            final RamlReport report = ramlDefinition.testAgainst(request, response);
            saver.addReport(report, request, response);
        } catch (Exception e) {
            try {
                saver.addReport(fromException(ramlDefinition.getRaml(), e), request, response);
            } catch (Exception e2) {
                System.err.println("Problem checking raml '" + ramlDefinition.getRaml().title() + "'");
                e.printStackTrace();
            }
        }
    }

    private RamlReport fromException(RamlApi raml, Exception cause) {