// Path: src/outbackcdx/UrlCanonicalizer.java
// public static class ConfigurationException extends Exception {
//     private static final long serialVersionUID = 1L;
//     public ConfigurationException(String msg) {
//         super(msg);
//     }
// }


import com.sun.management.OperatingSystemMXBean;
import com.sun.management.UnixOperatingSystemMXBean;
import outbackcdx.UrlCanonicalizer.ConfigurationException;
import outbackcdx.auth.Authorizer;
import outbackcdx.auth.JwtAuthorizer;
import outbackcdx.auth.KeycloakConfig;
import outbackcdx.auth.NullAuthorizer;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.URL;
import java.nio.channels.Channel;
import java.nio.channels.ServerSocketChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
                    server.start();
                    System.out.println("OutbackCDX http://" + (host == null ? "localhost" : host) + ":" + port);
                    synchronized (Main.class) {
                        Main.class.wait();
                    }
                } else {
                    ServerSocket socket = openSocket(host, port, inheritSocket);
                    Web.Server server = new Web.Server(socket, contextPath, controller, authorizer);
                    ExecutorService threadPool = Executors.newFixedThreadPool(webThreads);
                    for (String collectionUrl: collectionUrls) {
                        ChangePollingThread cpt = new ChangePollingThread(collectionUrl, pollingInterval, batchSize, dataStore);
                        cpt.setDaemon(true);
                        cpt.start();
                    }
                    try {
                        server.setAsyncRunner(threadPool);
                        server.start();
                        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                            server.stop();
                            dataStore.close();
                        }));
                        System.out.println("OutbackCDX http://" + (host == null ? "localhost" : host) + ":" + port + contextPath);
                        synchronized (Main.class) {
                            Main.class.wait();
                        }
                    } finally {
                        threadPool.shutdown();
                    }
                }
            }
// Path: src/outbackcdx/UrlCanonicalizer.java
// public static class ConfigurationException extends Exception {
//     private static final long serialVersionUID = 1L;
//     public ConfigurationException(String msg) {
//         super(msg);
//     }
// }


// Path: src/outbackcdx/Main.java
import com.sun.management.OperatingSystemMXBean;
import com.sun.management.UnixOperatingSystemMXBean;
import outbackcdx.UrlCanonicalizer.ConfigurationException;
import outbackcdx.auth.Authorizer;
import outbackcdx.auth.JwtAuthorizer;
import outbackcdx.auth.KeycloakConfig;
import outbackcdx.auth.NullAuthorizer;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.URL;
import java.nio.channels.Channel;
import java.nio.channels.ServerSocketChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

                    server.start();
                    System.out.println("OutbackCDX http://" + (host == null ? "localhost" : host) + ":" + port);
                    synchronized (Main.class) {
                        Main.class.wait();
                    }
                } else {
                    ServerSocket socket = openSocket(host, port, inheritSocket);
                    Web.Server server = new Web.Server(socket, contextPath, controller, authorizer);
                    ExecutorService threadPool = Executors.newFixedThreadPool(webThreads);
                    for (String collectionUrl: collectionUrls) {
                        ChangePollingThread cpt = new ChangePollingThread(collectionUrl, pollingInterval, batchSize, dataStore);
                        cpt.setDaemon(true);
                        cpt.start();
                    }
                    try {
                        server.setAsyncRunner(threadPool);
                        server.start();
                        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                            server.stop();
                            dataStore.close();
                        }));
                        System.out.println("OutbackCDX http://" + (host == null ? "localhost" : host) + ":" + port + contextPath);
                        synchronized (Main.class) {
                            Main.class.wait();
                        }
                    } finally {
                        threadPool.shutdown();
                    }
                }
            }
        } catch (InterruptedException | IOException | ConfigurationException e) {