// Path: src/main/java/com/thoughtworks/webstub/server/context/WebConsoleContext.java
// public class WebConsoleContext extends ContextHandler {
// 
//     public WebConsoleContext(HttpServer httpServer, String webAppRootDir) {
//         ResourceHandler handler = new ResourceHandler();
//         handler.setBaseResource(Resource.newClassPathResource(webAppRootDir));
//         handler.setDirectoriesListed(true);
//         handler.setWelcomeFiles(new String[] { "index.html" });
// 
//         this.setHandler(handler);
//         this.setContextPath("/");
// 
//         httpServer.addContext(this);
//     }
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/dsl/StubDsl.java
// public class StubDsl extends ConfigurationProvider {
// 
//     public StubDsl(ConfigurationListener listener) {
//         super(listener);
//     }
// 
//     public RequestBuilder get(String uri) {
//         return new RequestBuilder(this).withMethod("GET").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder post(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("POST").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder put(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("PUT").withUri(uri);
//     }
// 
//     public RequestBuilder delete(String uri) {
//         return new RequestBuilder(this).withMethod("DELETE").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder options(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("OPTIONS").withUri(uri);
//     }
// 
//     public RequestBuilder head(String uri) {
//         return new RequestBuilder(this).withMethod("HEAD").withUri(uri);
//     }
// 
//     public RequestBuilder trace(String uri) {
//         return new RequestBuilder(this).withMethod("TRACE").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder patch(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("PATCH").withUri(uri);
//     }
// 
//     public void reset() {
//         configurationCleared();
//     }
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/server/HttpServer.java
// public interface HttpServer {
//     void start();
//     void stop();
//     void addContext(ContextHandler contextHandler);
//     int port();
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/server/JettyHttpServer.java
// public class JettyHttpServer implements HttpServer {
// 
//     private Server server;
//     private ContextHandlerCollection handlerCollection;
// 
//     public JettyHttpServer(int port) {
//         server = new Server(port);
// 
//         handlerCollection = new ContextHandlerCollection();
//         server.setHandler(handlerCollection);
//     }
// 
//     public JettyHttpServer() {
//         // random port
//         this(0);
//     }
// 
//     @Override
//     public void addContext(ContextHandler contextHandler) {
//         handlerCollection.addHandler(contextHandler);
//         start(contextHandler);
//     }
// 
//     @Override
//     public int port() {
//         Connector[] connectors = server.getConnectors();
//         for (Connector connector : connectors) {
//             if (connector instanceof ServerConnector)
//                 return ((ServerConnector) connector).getLocalPort();
//         }
// 
//         throw new IllegalStateException("Couldn't find a server connector; this is absurd!");
//     }
// 
//     @Override
//     public void start() {
//         try {
//             server.start();
//         } catch (Exception e) {
//             throw new RuntimeException("Unable to start server", e);
//         }
//     }
// 
//     @Override
//     public void stop() {
//         try {
//             server.stop();
//         } catch (Exception e) {
//             throw new RuntimeException("Unable to stop server", e);
//         }
//     }
// 
//     private void start(ContextHandler contextHandler) {
//         try {
//             contextHandler.start();
//         } catch (Exception e) {
//             throw new RuntimeException("Error starting context: " + contextHandler.getDisplayName(), e);
//         }
//     }
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/server/context/ConfigurableContext.java
// public class ConfigurableContext implements ConfigurationListener {
//     private Configurations configurations;
// 
//     public ConfigurableContext(HttpServer server, String contextRoot) {
//         assertNotBlank(contextRoot);
// 
//         ServletContextHandler context = new ServletContextHandler(sanitized(contextRoot));
//         context.addServlet("/__status__", new StatusServlet(200));
// 
//         configurations = new Configurations();
//         context.addServlet("/", new ConfigurableServlet(configurations));
// 
//         server.addContext(context);
//     }
// 
//     @Override
//     public void configurationCreated(HttpConfiguration configuration) {
//         configurations.add(configuration);
//     }
// 
//     @Override
//     public void configurationCleared() {
//         configurations.reset();
//     }
// 
//     private void assertNotBlank(String contextRoot) {
//         if (isBlank(contextRoot))
//             throw new IllegalArgumentException("Invalid context root");
//     }
// 
//     private String sanitized(String contextRoot) {
//         return contextRoot.startsWith("/") ? contextRoot : ("/" + contextRoot);
//     }
// }


import com.thoughtworks.webstub.server.context.WebConsoleContext;
import com.thoughtworks.webstub.dsl.StubDsl;
import com.thoughtworks.webstub.server.HttpServer;
import com.thoughtworks.webstub.server.JettyHttpServer;
import com.thoughtworks.webstub.server.context.ConfigurableContext;
package com.thoughtworks.webstub;


public class StubServer {
    public static StubServer newServer(int port) {
        return new StubServer(new JettyHttpServer(port));
    }

    public static StubServer newServer() {
        return new StubServer(new JettyHttpServer());
    }

    private HttpServer httpServer;

    private StubServer(HttpServer httpServer) {
        this.httpServer = httpServer;
    }

    public StubServer withWebConsole() {
        new WebConsoleContext(httpServer, "webconsole");
        return this;
    }

    public StubDsl stub(String contextRoot) {
// Path: src/main/java/com/thoughtworks/webstub/server/context/WebConsoleContext.java
// public class WebConsoleContext extends ContextHandler {
// 
//     public WebConsoleContext(HttpServer httpServer, String webAppRootDir) {
//         ResourceHandler handler = new ResourceHandler();
//         handler.setBaseResource(Resource.newClassPathResource(webAppRootDir));
//         handler.setDirectoriesListed(true);
//         handler.setWelcomeFiles(new String[] { "index.html" });
// 
//         this.setHandler(handler);
//         this.setContextPath("/");
// 
//         httpServer.addContext(this);
//     }
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/dsl/StubDsl.java
// public class StubDsl extends ConfigurationProvider {
// 
//     public StubDsl(ConfigurationListener listener) {
//         super(listener);
//     }
// 
//     public RequestBuilder get(String uri) {
//         return new RequestBuilder(this).withMethod("GET").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder post(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("POST").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder put(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("PUT").withUri(uri);
//     }
// 
//     public RequestBuilder delete(String uri) {
//         return new RequestBuilder(this).withMethod("DELETE").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder options(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("OPTIONS").withUri(uri);
//     }
// 
//     public RequestBuilder head(String uri) {
//         return new RequestBuilder(this).withMethod("HEAD").withUri(uri);
//     }
// 
//     public RequestBuilder trace(String uri) {
//         return new RequestBuilder(this).withMethod("TRACE").withUri(uri);
//     }
// 
//     public EntityEnclosingRequestBuilder patch(String uri) {
//         return new EntityEnclosingRequestBuilder(this).withMethod("PATCH").withUri(uri);
//     }
// 
//     public void reset() {
//         configurationCleared();
//     }
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/server/HttpServer.java
// public interface HttpServer {
//     void start();
//     void stop();
//     void addContext(ContextHandler contextHandler);
//     int port();
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/server/JettyHttpServer.java
// public class JettyHttpServer implements HttpServer {
// 
//     private Server server;
//     private ContextHandlerCollection handlerCollection;
// 
//     public JettyHttpServer(int port) {
//         server = new Server(port);
// 
//         handlerCollection = new ContextHandlerCollection();
//         server.setHandler(handlerCollection);
//     }
// 
//     public JettyHttpServer() {
//         // random port
//         this(0);
//     }
// 
//     @Override
//     public void addContext(ContextHandler contextHandler) {
//         handlerCollection.addHandler(contextHandler);
//         start(contextHandler);
//     }
// 
//     @Override
//     public int port() {
//         Connector[] connectors = server.getConnectors();
//         for (Connector connector : connectors) {
//             if (connector instanceof ServerConnector)
//                 return ((ServerConnector) connector).getLocalPort();
//         }
// 
//         throw new IllegalStateException("Couldn't find a server connector; this is absurd!");
//     }
// 
//     @Override
//     public void start() {
//         try {
//             server.start();
//         } catch (Exception e) {
//             throw new RuntimeException("Unable to start server", e);
//         }
//     }
// 
//     @Override
//     public void stop() {
//         try {
//             server.stop();
//         } catch (Exception e) {
//             throw new RuntimeException("Unable to stop server", e);
//         }
//     }
// 
//     private void start(ContextHandler contextHandler) {
//         try {
//             contextHandler.start();
//         } catch (Exception e) {
//             throw new RuntimeException("Error starting context: " + contextHandler.getDisplayName(), e);
//         }
//     }
// }
// 
// Path: src/main/java/com/thoughtworks/webstub/server/context/ConfigurableContext.java
// public class ConfigurableContext implements ConfigurationListener {
//     private Configurations configurations;
// 
//     public ConfigurableContext(HttpServer server, String contextRoot) {
//         assertNotBlank(contextRoot);
// 
//         ServletContextHandler context = new ServletContextHandler(sanitized(contextRoot));
//         context.addServlet("/__status__", new StatusServlet(200));
// 
//         configurations = new Configurations();
//         context.addServlet("/", new ConfigurableServlet(configurations));
// 
//         server.addContext(context);
//     }
// 
//     @Override
//     public void configurationCreated(HttpConfiguration configuration) {
//         configurations.add(configuration);
//     }
// 
//     @Override
//     public void configurationCleared() {
//         configurations.reset();
//     }
// 
//     private void assertNotBlank(String contextRoot) {
//         if (isBlank(contextRoot))
//             throw new IllegalArgumentException("Invalid context root");
//     }
// 
//     private String sanitized(String contextRoot) {
//         return contextRoot.startsWith("/") ? contextRoot : ("/" + contextRoot);
//     }
// }


// Path: src/main/java/com/thoughtworks/webstub/StubServer.java
import com.thoughtworks.webstub.server.context.WebConsoleContext;
import com.thoughtworks.webstub.dsl.StubDsl;
import com.thoughtworks.webstub.server.HttpServer;
import com.thoughtworks.webstub.server.JettyHttpServer;
import com.thoughtworks.webstub.server.context.ConfigurableContext;

package com.thoughtworks.webstub;


public class StubServer {
    public static StubServer newServer(int port) {
        return new StubServer(new JettyHttpServer(port));
    }

    public static StubServer newServer() {
        return new StubServer(new JettyHttpServer());
    }

    private HttpServer httpServer;

    private StubServer(HttpServer httpServer) {
        this.httpServer = httpServer;
    }

    public StubServer withWebConsole() {
        new WebConsoleContext(httpServer, "webconsole");
        return this;
    }

    public StubDsl stub(String contextRoot) {
        if (contextRoot.equals("/"))