Bash everything until it all works again
diff --git a/src/waitress/__init__.py b/src/waitress/__init__.py
index 39f43ae..bbb99da 100644
--- a/src/waitress/__init__.py
+++ b/src/waitress/__init__.py
@@ -3,14 +3,14 @@
 from waitress.server import create_server
 
 
-def serve(app, opts, **kw):
+def serve(app, **kw):
     _server = kw.pop("_server", create_server)  # test shim
     _quiet = kw.pop("_quiet", False)  # test shim
     _profile = kw.pop("_profile", False)  # test shim
     if not _quiet:  # pragma: no cover
         # idempotent if logging has already been set up
         logging.basicConfig()
-    server = _server(app, opts, **kw)
+    server = _server(app, **kw)
     if not _quiet:  # pragma: no cover
         server.print_listen("Serving on http://{}:{}")
     if _profile:  # pragma: no cover
@@ -20,7 +20,7 @@
 
 
 def serve_paste(app, global_conf, **kw):
-    serve(app, {}, **kw)
+    serve(app, **kw)
     return 0
 
 
diff --git a/src/waitress/adjustments.py b/src/waitress/adjustments.py
index 185bd82..afc1efa 100644
--- a/src/waitress/adjustments.py
+++ b/src/waitress/adjustments.py
@@ -11,9 +11,8 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Adjustments are tunable parameters.
-"""
-import getopt
+"""Adjustments are tunable parameters."""
+
 import socket
 import warnings
 
@@ -43,7 +42,7 @@
 
 def asoctal(s):
     """Convert the given octal string to an actual number."""
-    return int(s, 8)
+    return s if isinstance(s, int) else int(s, 8)
 
 
 def aslist_cronly(value):
@@ -56,6 +55,8 @@
     """Return a list of strings, separating the input based on newlines
     and, if flatten=True (the default), also split on spaces within
     each line."""
+    if isinstance(value, list):
+        return value
     values = aslist_cronly(value)
     result = []
     for value in values:
@@ -289,7 +290,7 @@
     # (or when using the Proxy settings, without forwarding a Host header)
     server_name = "waitress.invalid"
 
-    def __init__(self, opts, **kw):
+    def __init__(self, **kw):
         if "listen" in kw and ("host" in kw or "port" in kw):
             raise ValueError("host or port may not be set if listen is set.")
 
@@ -313,12 +314,6 @@
                 "send_bytes will be removed in a future release", DeprecationWarning
             )
 
-        # opts are already validated, so that we set them as is
-        for k, v in opts.items():
-            if k not in self._param_map:
-                raise ValueError("Unknown adjustment %r" % k)
-            setattr(self, k, v)
-
         for k, v in kw.items():
             if k not in self._param_map:
                 raise ValueError("Unknown adjustment %r" % k)
@@ -453,47 +448,6 @@
         self.check_sockets(self.sockets)
 
     @classmethod
-    def parse_args(cls, argv):
-        """Pre-parse command line arguments for input into __init__.  Note that
-        this does not cast values into adjustment types, it just creates a
-        dictionary suitable for passing into __init__, where __init__ does the
-        casting.
-        """
-        long_opts = ["help", "call"]
-        for opt, cast in cls._params:
-            opt = opt.replace("_", "-")
-            if cast is asbool:
-                long_opts.append(opt)
-                long_opts.append("no-" + opt)
-            else:
-                long_opts.append(opt + "=")
-
-        kw = {
-            "help": False,
-            "call": False,
-        }
-
-        opts, args = getopt.getopt(argv, "", long_opts)
-        for opt, value in opts:
-            param = opt.lstrip("-").replace("-", "_")
-
-            if param == "listen":
-                kw["listen"] = "{} {}".format(kw.get("listen", ""), value)
-                continue
-
-            if param.startswith("no_"):
-                param = param[3:]
-                kw[param] = "false"
-            elif param in ("help", "call"):
-                kw[param] = True
-            elif cls._param_map[param] is asbool:
-                kw[param] = "true"
-            else:
-                kw[param] = value
-
-        return kw, args
-
-    @classmethod
     def check_sockets(cls, sockets):
         has_unix_socket = False
         has_inet_socket = False
diff --git a/src/waitress/runner.py b/src/waitress/runner.py
index b69d9ca..5056943 100644
--- a/src/waitress/runner.py
+++ b/src/waitress/runner.py
@@ -12,9 +12,8 @@
 #
 ##############################################################################
 """Command line runner."""
-import warnings
-import re
-import getopt
+
+from argparse import ArgumentParser, BooleanOptionalAction
 import logging
 import operator as op
 import os
@@ -22,33 +21,11 @@
 import pathlib
 import pkgutil
 import sys
-from argparse import ArgumentParser, BooleanOptionalAction
-from dataclasses import dataclass
-from ipaddress import ip_address
 from urllib.parse import urlparse
-import importlib
-from waitress import serve
-from waitress.adjustments import Adjustments
+
+from waitress import adjustments, serve
 from waitress.utilities import logger
 
-
-def show_exception(stream):
-    exc_type, exc_value = sys.exc_info()[:2]
-    args = getattr(exc_value, "args", None)
-    print(
-        ("There was an exception ({}) importing your module.\n").format(
-            exc_type.__name__,
-        ),
-        file=stream,
-    )
-    if args:
-        print("It had these arguments: ", file=stream)
-        for idx, arg in enumerate(args, start=1):
-            print(f"{idx}. {arg}\n", file=stream)
-    else:
-        print("It had no arguments.", file=stream)
-
-
 host_and_port = op.attrgetter("hostname", "port")
 
 
@@ -57,66 +34,39 @@
     res = urlparse(f"scheme://{value}")
 
     if not all(host_and_port(res)):
-        raise ValueError("Not a socket! Should HOST:PORT", value)
+        raise ValueError("Not a valid host and port! Should HOST:PORT", value)
 
-    return str(ip_address(res.hostname)), str(res.port)
+    return res.hostname, str(res.port)
 
 
-def _validate_opts(opts):
-    if hasattr(opts, 'listen') and (hasattr(opts, 'host') or hasattr(opts, 'port')):
-        raise ValueError("host or port may not be set if listen is set.")
-
-    if hasattr(opts, 'unix_socket') and (hasattr(opts, 'host') or hasattr(opts, 'port')):
-        raise ValueError("unix_socket may not be set if host or port is set")
-
-    if hasattr(opts, 'unix_socket') and hasattr(opts, 'listen'):
-        raise ValueError("unix_socket may not be set if listen is set")
-
-
-@dataclass(frozen=True)
-class DEFAULTS:
-    BACKLOG = 1024
-    HOST = "0.0.0.0"
-    IDENT = "waitress"
-    PORT = 8080
-    THREADS = 4
-    UNIX_SOCKET_PERMS = "600"
-    URL_SCHEME = "http"
-    # fmt: off
-    ASYNCORE_LOOP_TIMEOUT   = 1     # second
-    CHANNEL_TIMEOUT         = 120   # seconds
-    CHANNEL_REQUEST_LOOKAHEAD = 0
-    CLEANUP_INTERVAL        = 30    # seconds
-    CONNECTION_LIMIT        = 100
-    INBUF_HIGH_WATERMARK    = 16777216    # 16  MB
-    INBUF_OVERFLOW          = 524288      # 512 KB
-    MAX_REQUEST_BODY_SIZE   = 1073741824  # 1   GB
-    MAX_REQUEST_HEADER_SIZE = 262144      # 256 KB
-    OUTBUF_HIGH_WATERMARK   = 16777216    # 16  MB
-    OUTBUF_OVERFLOW         = 1048576     # 1   MB
-    RECV_BYTES              = 8192        # 8   KB
-    SEND_BYTES              = 18000
-    # fmt: on
-
-
-def run(argv=sys.argv, _serve=serve):
-    """Command line runner."""
+def make_parser():
     parser = ArgumentParser()
     # Standard options
     parser.add_argument(
-        "--app",
-        required=True,
-        help="Specify WSGI application to run. Required. Can be passed at any position.",
-    )
-    parser.add_argument(
         "--call",
         action="store_true",
         help="Call the given object to get the WSGI application.",
     )
-    parser.add_argument(
+    listener = parser.add_mutually_exclusive_group(required=False)
+    listener.add_argument(
+        "--listen",
+        action="append",
+        type=_valid_socket,
+        metavar="HOST:PORT",
+        help="Tell waitress to listen on an ip port combination.",
+    )
+    listener.add_argument(
+        "--unix-socket",
+        type=pathlib.Path,
+        help="""Path of Unix socket. If a socket path is specified, a
+Unix domain socket is made instead of the usual inet domain socket.
+
+Not available on Windows.""",
+    )
+    listener.add_argument(
         "--host",
-        type=ip_address,
-        default=DEFAULTS.HOST,
+        type=str,
+        default=adjustments.Adjustments.host,
         help="""Hostname or IP address on which to listen.
 Note: may not be used together with `--listen`.
 
@@ -125,42 +75,32 @@
     parser.add_argument(
         "--port",
         type=int,
-        default=DEFAULTS.PORT,
-        help="""TCP port on which to listen.
-Note: may not be used together with `--listen`.
+        default=adjustments.Adjustments.port,
+        help="""TCP port on which to listen. Ignored if --listen or --unix-socket are used.
 
 Default is %(default)s.""",
     )
-    parser.add_argument(
-        "--listen",
-        type=_valid_socket,
-        action='append',
-        help="Tell waitress to listen on an ip port combination.",
-    )
-    parser.add_argument(
-        "--ipv4", action=BooleanOptionalAction, help="Toggle on/off IPv4 support."
-    )
-    parser.add_argument(
-        "--ipv6", action=BooleanOptionalAction, help="Toggle on/off IPv6 support."
-    )
-    parser.add_argument(
-        "--unix-socket",
-        type=pathlib.Path,
-        help="""Path of Unix socket. If a socket path is specified, a
-Unix domain socket is made instead of the usual inet domain socket.
 
-Not available on Windows.""",
+    parser.add_argument(
+        "--ipv4",
+        action=BooleanOptionalAction,
+        help="Toggle on/off IPv4 support.",
+    )
+    parser.add_argument(
+        "--ipv6",
+        action=BooleanOptionalAction,
+        help="Toggle on/off IPv6 support.",
     )
     parser.add_argument(
         "--unix-socket-perms",
-        type=lambda v: int(v, base=8),
-        default=DEFAULTS.UNIX_SOCKET_PERMS,
+        type=adjustments.asoctal,
+        default=oct(adjustments.Adjustments.unix_socket_perms),
         help="""Octal permissions to use for the Unix domain socket.
 Default is %(default)s.""",
     )
     parser.add_argument(
         "--url-scheme",
-        default=DEFAULTS.URL_SCHEME,
+        default=adjustments.Adjustments.url_scheme,
         help="Default `wsgi.url_scheme` value. Default is %(default)r.",
     )
     parser.add_argument(
@@ -173,7 +113,7 @@
     )
     parser.add_argument(
         "--ident",
-        default=DEFAULTS.IDENT,
+        default=adjustments.Adjustments.ident,
         help="""Server identity used in the 'Server' header in responses.
 Default is %(default)r.""",
     )
@@ -181,37 +121,36 @@
     parser.add_argument(
         "--threads",
         type=int,
-        default=DEFAULTS.THREADS,
+        default=adjustments.Adjustments.threads,
         help="""Number of threads used to process application logic.
 Default is %(default)s.""",
     )
     parser.add_argument(
         "--backlog",
         type=int,
-        default=DEFAULTS.BACKLOG,
+        default=adjustments.Adjustments.backlog,
         help="""Connection backlog for the server. Default is %(default)s.""",
     )
     parser.add_argument(
         "--recv-bytes",
         type=int,
-        default=DEFAULTS.RECV_BYTES,
+        default=adjustments.Adjustments.recv_bytes,
         help="""Number of bytes to request when calling `socket.recv()`.
 Default is %(default)s bytes.""",
     )
     parser.add_argument(
         "--send-bytes",
         type=int,
-        default=DEFAULTS.SEND_BYTES,
+        default=adjustments.Adjustments.send_bytes,
         help="""Number of bytes to send to `socket.send()`.
 Note: multiples of 9000 should avoid partly-filled TCP packets.
 
 Default is %(default)s bytes.""",
-
     )
     parser.add_argument(
         "--outbuf-overflow",
         type=int,
-        default=DEFAULTS.OUTBUF_OVERFLOW,
+        default=adjustments.Adjustments.outbuf_overflow,
         help="""A temporary file should be created if the pending output is larger
 than this.
 
@@ -220,7 +159,7 @@
     parser.add_argument(
         "--outbuf-high-watermark",
         type=int,
-        default=DEFAULTS.OUTBUF_HIGH_WATERMARK,
+        default=adjustments.Adjustments.outbuf_high_watermark,
         help="""The `app_iter` will pause when pending output is larger than
 this value and will resume once enough data is written to the socket to fall
 below this threshold.
@@ -230,7 +169,7 @@
     parser.add_argument(
         "--inbuf-overflow",
         type=int,
-        default=DEFAULTS.INBUF_OVERFLOW,
+        default=adjustments.Adjustments.inbuf_overflow,
         help="""A temporary file should be created if the pending input is larger
 than this.
 
@@ -239,7 +178,7 @@
     parser.add_argument(
         "--connection-limit",
         type=int,
-        default=DEFAULTS.CONNECTION_LIMIT,
+        default=adjustments.Adjustments.connection_limit,
         help="""Stop creating new channels if too many are already active.
 
 Default is %(default)s.""",
@@ -247,7 +186,7 @@
     parser.add_argument(
         "--cleanup-interval",
         type=int,
-        default=DEFAULTS.CLEANUP_INTERVAL,
+        default=adjustments.Adjustments.cleanup_interval,
         help="""Minimum seconds between cleaning up inactive channels.
 See `--channel-timeout` option.
 
@@ -256,7 +195,7 @@
     parser.add_argument(
         "--channel-timeout",
         type=int,
-        default=DEFAULTS.CHANNEL_TIMEOUT,
+        default=adjustments.Adjustments.channel_timeout,
         help="""Maximum number of seconds to leave inactive connections open.
 'Inactive' is defined as 'has received no data from the client and has sent
 no data to the client'.
@@ -266,21 +205,21 @@
     parser.add_argument(
         "--max-request-header-size",
         type=int,
-        default=DEFAULTS.MAX_REQUEST_HEADER_SIZE,
+        default=adjustments.Adjustments.max_request_header_size,
         help="""Maximum size of all request headers combined.
 Default is %(default)s bytes.""",
     )
     parser.add_argument(
         "--max-request-body-size",
         type=int,
-        default=DEFAULTS.MAX_REQUEST_BODY_SIZE,
+        default=adjustments.Adjustments.max_request_body_size,
         help="""Maximum size of request body.
 Default is %(default)s bytes.""",
     )
     parser.add_argument(
         "--asyncore-loop-timeout",
         type=int,
-        default=DEFAULTS.ASYNCORE_LOOP_TIMEOUT,
+        default=adjustments.Adjustments.asyncore_loop_timeout,
         help="""The timeout value in seconds passed to `asyncore.loop()`.
 Default is %(default)s.""",
     )
@@ -295,7 +234,7 @@
     parser.add_argument(
         "--channel-request-lookahead",
         type=int,
-        default=DEFAULTS.CHANNEL_REQUEST_LOOKAHEAD,
+        default=adjustments.Adjustments.channel_request_lookahead,
         help="""Allows channels to stay readable and buffer more requests up to
 the given maximum even if a request is already being processed. This allows
 detecting if a client closed the connection while its request is being processed.
@@ -319,6 +258,27 @@
 Default is 'no'.""",
     )
 
+    # This hack is needed to support the use of a flag and the legacy
+    # positional syntax.
+    parser.add_argument(
+        "--app",
+        required=False,
+        action="append",
+        help="Specify WSGI application to run. Required, but can be given without the flag for backward compatibility.",
+    )
+    parser.add_argument(
+        "app",
+        nargs="?",
+        action="append",
+        metavar="APP",
+        help="Legacy method for specifying the WSGI application to run.",
+    )
+    return parser
+
+
+def run(argv=sys.argv, _serve=serve):
+    """Command line runner."""
+    parser = make_parser()
     args = parser.parse_args(argv[1:])
 
     # set a default level for the logger only if it hasn't been set explicitly
@@ -330,26 +290,29 @@
     # Add the current directory onto sys.path
     sys.path.append(os.getcwd())
 
+    apps = list(filter(None, args.app))
+    if len(apps) != 1:
+        print("Error: Specify one and only one WSGI application", file=sys.stderr)
+        parser.print_help(file=sys.stderr)
+        return 1
+    app_name = apps[0]
+    del args.app
+
     # Get the WSGI function.
     try:
-        app = pkgutil.resolve_name(args.app)
-    except ImportError:
-        print(f"Bad module {module!r}", file=sys.stderr)
+        app = pkgutil.resolve_name(app_name)
+    except (ImportError, AttributeError, ValueError) as exc:
+        print(f"Error: {exc}", file=sys.stderr)
         parser.print_help(file=sys.stderr)
-        show_exception(sys.stderr)
-        return 1
-    except (AttributeError, ValueError):
-        print(f"Bad object name {obj_name!r}", file=sys.stderr)
-        parser.print_help(file=sys.stderr)
-        show_exception(sys.stderr)
         return 1
     if args.call:
         app = app()
     del args.call
+    if args.listen:
+        del args.port
+        del args.host
 
-    from pprint import pprint as pp; pp(vars(args))
     opts = {k: v for k, v in vars(args).items() if v is not None}
-    _validate_opts(opts)
-    _serve(app, opts)
+    _serve(app, **opts)
 
     return 0
diff --git a/src/waitress/server.py b/src/waitress/server.py
index 75a35bf..2f10560 100644
--- a/src/waitress/server.py
+++ b/src/waitress/server.py
@@ -30,7 +30,6 @@
 
 def create_server(
     application,
-    opts, # dict
     map=None,
     _start=True,  # test shim
     _sock=None,  # test shim
@@ -42,7 +41,7 @@
             'The "app" passed to ``create_server`` was ``None``.  You forgot '
             "to return a WSGI app within your application."
         )
-    adj = Adjustments(opts, **kw)
+    adj = Adjustments(**kw)
 
     if map is None:  # pragma: nocover
         map = {}
@@ -192,7 +191,7 @@
         **kw,
     ):
         if adj is None:
-            adj = Adjustments({}, **kw)
+            adj = Adjustments(**kw)
 
         if adj.trusted_proxy or adj.clear_untrusted_proxy_headers:
             # wrap the application to deal with proxy headers
diff --git a/tests/test_adjustments.py b/tests/test_adjustments.py
index 9b7cf43..25957ce 100644
--- a/tests/test_adjustments.py
+++ b/tests/test_adjustments.py
@@ -103,7 +103,7 @@
     def _makeOne(self, **kw):
         from waitress.adjustments import Adjustments
 
-        return Adjustments({}, **kw)
+        return Adjustments(**kw)
 
     def test_goodvars(self):
         inst = self._makeOne(
@@ -385,93 +385,13 @@
         self.assertEqual(inst.ident, "specific_header")
 
 
-class TestCLI(unittest.TestCase):
-    def parse(self, argv):
-        from waitress.adjustments import Adjustments
-
-        return Adjustments.parse_args(argv)
-
-    def assertDictContainsSubset(self, subset, dictionary):
-        self.assertTrue(set(subset.items()) <= set(dictionary.items()))
-
-    def test_noargs(self):
-        opts, args = self.parse([])
-        self.assertDictEqual(opts, {"call": False, "help": False})
-        self.assertSequenceEqual(args, [])
-
-    def test_help(self):
-        opts, args = self.parse(["--help"])
-        self.assertDictEqual(opts, {"call": False, "help": True})
-        self.assertSequenceEqual(args, [])
-
-    def test_call(self):
-        opts, args = self.parse(["--call"])
-        self.assertDictEqual(opts, {"call": True, "help": False})
-        self.assertSequenceEqual(args, [])
-
-    def test_both(self):
-        opts, args = self.parse(["--call", "--help"])
-        self.assertDictEqual(opts, {"call": True, "help": True})
-        self.assertSequenceEqual(args, [])
-
-    def test_positive_boolean(self):
-        opts, args = self.parse(["--expose-tracebacks"])
-        self.assertDictContainsSubset({"expose_tracebacks": "true"}, opts)
-        self.assertSequenceEqual(args, [])
-
-    def test_negative_boolean(self):
-        opts, args = self.parse(["--no-expose-tracebacks"])
-        self.assertDictContainsSubset({"expose_tracebacks": "false"}, opts)
-        self.assertSequenceEqual(args, [])
-
-    def test_cast_params(self):
-        opts, args = self.parse(
-            ["--host=localhost", "--port=80", "--unix-socket-perms=777"]
-        )
-        self.assertDictContainsSubset(
-            {
-                "host": "localhost",
-                "port": "80",
-                "unix_socket_perms": "777",
-            },
-            opts,
-        )
-        self.assertSequenceEqual(args, [])
-
-    def test_listen_params(self):
-        opts, args = self.parse(
-            [
-                "--listen=test:80",
-            ]
-        )
-
-        self.assertDictContainsSubset({"listen": " test:80"}, opts)
-        self.assertSequenceEqual(args, [])
-
-    def test_multiple_listen_params(self):
-        opts, args = self.parse(
-            [
-                "--listen=test:80",
-                "--listen=test:8080",
-            ]
-        )
-
-        self.assertDictContainsSubset({"listen": " test:80 test:8080"}, opts)
-        self.assertSequenceEqual(args, [])
-
-    def test_bad_param(self):
-        import getopt
-
-        self.assertRaises(getopt.GetoptError, self.parse, ["--no-host"])
-
-
 if hasattr(socket, "AF_UNIX"):
 
     class TestUnixSocket(unittest.TestCase):
         def _makeOne(self, **kw):
             from waitress.adjustments import Adjustments
 
-            return Adjustments({}, **kw)
+            return Adjustments(**kw)
 
         def test_dont_mix_internet_and_unix_sockets(self):
             sockets = [
diff --git a/tests/test_functional.py b/tests/test_functional.py
index 5c65801..d3f1b37 100644
--- a/tests/test_functional.py
+++ b/tests/test_functional.py
@@ -3,7 +3,6 @@
 import logging
 import multiprocessing
 import os
-import signal
 import socket
 import string
 import subprocess
diff --git a/tests/test_init.py b/tests/test_init.py
index 7c6e10d..58b5c2e 100644
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -5,7 +5,7 @@
     def _callFUT(self, app, **kw):
         from waitress import serve
 
-        return serve(app, {}, **kw)
+        return serve(app, **kw)
 
     def test_it(self):
         server = DummyServerFactory()
@@ -34,7 +34,7 @@
 class DummyServerFactory:
     ran = False
 
-    def __call__(self, app, opts, **kw):
+    def __call__(self, app, **kw):
         self.adj = DummyAdj(kw)
         self.app = app
         self.kw = kw
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 5560a52..4195295 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -35,7 +35,7 @@
 
 class TestHTTPRequestParser(unittest.TestCase):
     def setUp(self):
-        my_adj = Adjustments({})
+        my_adj = Adjustments()
         self.parser = HTTPRequestParser(my_adj)
 
     def test_get_body_stream_None(self):
@@ -582,7 +582,7 @@
 
 class TestHTTPRequestParserIntegration(unittest.TestCase):
     def setUp(self):
-        my_adj = Adjustments({})
+        my_adj = Adjustments()
         self.parser = HTTPRequestParser(my_adj)
 
     def feed(self, data):
diff --git a/tests/test_runner.py b/tests/test_runner.py
index 2b91f1f..39109f7 100644
--- a/tests/test_runner.py
+++ b/tests/test_runner.py
@@ -3,48 +3,43 @@
 import sys
 import unittest
 
-from waitress import runner
+from waitress import adjustments, runner
 
 
 def test_valid_socket():
-    assert runner._valid_socket('0.0.0.0:42') == ('0.0.0.0', '42')
-    assert runner._valid_socket('[2001:db8::1]:42') == ('2001:db8::1', '42')
+    assert runner._valid_socket("0.0.0.0:42") == ("0.0.0.0", "42")
+    assert runner._valid_socket("[2001:db8::1]:42") == ("2001:db8::1", "42")
 
 
 class Test_run(unittest.TestCase):
     def match_output(self, argv, code, regex):
         argv = ["waitress-serve"] + argv
         with capture() as captured:
-            self.assertEqual(runner.run(argv=argv), code)
+            try:
+                self.assertEqual(runner.run(argv=argv), code)
+            except SystemExit as exit:
+                self.assertEqual(exit.code, code)
         self.assertRegex(captured.getvalue(), regex)
         captured.close()
 
-    def test_bad(self):
-        self.match_output(["--app=foo:bar", "--bad-opt"], 2, "error: unrecognized arguments: waitress-serve --bad-opt")
-
-    def test_help(self):
-        self.match_output(["--help"], 0, "^usage: waitress-serve")
-
     def test_no_app(self):
-        self.match_output([], 2, "error: the following arguments are required: --app")
+        self.match_output([], 1, "^Error: Specify one and only one WSGI application")
 
     def test_multiple_apps_app(self):
-        self.match_output(["--app", "a:a", "--app", "b:b"], 1, "^Error: Specify one application only")
+        self.match_output(
+            ["--app", "a:a", "--app", "b:b"],
+            1,
+            "^Error: Specify one and only one WSGI application",
+        )
 
     def test_bad_apps_app(self):
         self.match_output(["--app", "a"], 1, "^Error: No module named 'a'")
 
     def test_bad_app_module(self):
-        self.match_output(["--app", "nonexistent:a"], 1, "^Error: No module named 'nonexistent'")
-
         self.match_output(
             ["--app", "nonexistent:a"],
             1,
-            (
-                r"There was an exception \((ImportError|ModuleNotFoundError)\) "
-                "importing your module.\n\nIt had these arguments: \n"
-                "1. No module named '?nonexistent'?"
-            ),
+            "^Error: No module named 'nonexistent'",
         )
 
     def test_cwd_added_to_path(self):
@@ -57,7 +52,8 @@
             os.chdir(os.path.dirname(__file__))
             argv = [
                 "waitress-serve",
-                "--app", "fixtureapps.runner:app",
+                "--app",
+                "fixtureapps.runner:app",
             ]
             self.assertEqual(runner.run(argv=argv, _serve=null_serve), 0)
         finally:
@@ -76,7 +72,7 @@
 
         def check_server(app, **kw):
             self.assertIs(app, _apps.app)
-            self.assertDictEqual(kw, {"port": "80"})
+            self.assertEqual(kw["port"], 80)
 
         argv = [
             "waitress-serve",
@@ -85,12 +81,30 @@
         ]
         self.assertEqual(runner.run(argv=argv, _serve=check_server), 0)
 
+    def test_good_listen(self):
+        from tests.fixtureapps import runner as _apps
+
+        def check_server(app, **kw):
+            self.assertIs(app, _apps.app)
+            adj = adjustments.Adjustments(**kw)
+            self.assertListEqual(
+                [entry[3] for entry in adj.listen],
+                [("127.0.0.1", 80)],
+            )
+
+        argv = [
+            "waitress-serve",
+            "--listen=127.0.0.1:80",
+            "--app=tests.fixtureapps.runner:app",
+        ]
+        self.assertEqual(runner.run(argv=argv, _serve=check_server), 0)
+
     def test_returned_app(self):
         from tests.fixtureapps import runner as _apps
 
         def check_server(app, **kw):
             self.assertIs(app, _apps.app)
-            self.assertDictEqual(kw, {"port": "80"})
+            self.assertEqual(kw["port"], 80)
 
         argv = [
             "waitress-serve",
@@ -100,36 +114,48 @@
         ]
         self.assertEqual(runner.run(argv=argv, _serve=check_server), 0)
 
-
-class Test_helper(unittest.TestCase):
-    def test_exception_logging(self):
-        from waitress.runner import show_exception
-
-        regex = (
-            r"There was an exception \(ImportError\) importing your module."
-            r"\n\nIt had these arguments: \n1. My reason"
+    def test_bad_listen(self):
+        self.match_output(
+            [
+                "--listen=foo/bar",
+                "--app=tests.fixtureapps.runner:app",
+            ],
+            2,
+            "error: argument --listen: invalid _valid_socket value: 'foo/bar'",
         )
 
-        with capture() as captured:
-            try:
-                raise ImportError("My reason")
-            except ImportError:
-                self.assertIsNone(show_exception(sys.stderr))
-            self.assertRegex(captured.getvalue(), regex)
-        captured.close()
-
-        regex = (
-            r"There was an exception \(ImportError\) importing your module."
-            r"\n\nIt had no arguments."
+    def test_inet(self):
+        self.match_output(
+            [
+                "--listen=127.0.0.1:8080",
+                "--host=127.0.0.1",
+                "--app=tests.fixtureapps.runner:app",
+            ],
+            2,
+            "error: argument --host: not allowed with argument --listen",
         )
 
-        with capture() as captured:
-            try:
-                raise ImportError
-            except ImportError:
-                self.assertIsNone(show_exception(sys.stderr))
-            self.assertRegex(captured.getvalue(), regex)
-        captured.close()
+    def test_inet_and_unix_socket(self):
+        self.match_output(
+            [
+                "--host=127.0.0.1",
+                "--unix-socket=/tmp/waitress.sock",
+                "--app=tests.fixtureapps.runner:app",
+            ],
+            2,
+            "error: argument --unix-socket: not allowed with argument --host",
+        )
+
+    def test_listen_and_unix_socket(self):
+        self.match_output(
+            [
+                "--listen=127.0.0.1:8080",
+                "--unix-socket=/tmp/waitress.sock",
+                "--app=tests.fixtureapps.runner:app",
+            ],
+            2,
+            "error: argument --unix-socket: not allowed with argument --listen",
+        )
 
 
 @contextlib.contextmanager
diff --git a/tests/test_server.py b/tests/test_server.py
index 006bf10..cede49a 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -22,7 +22,6 @@
 
         self.inst = create_server(
             application,
-            {},
             host=host,
             port=port,
             map=map,
@@ -58,7 +57,6 @@
 
         self.inst = create_server(
             app,
-            {},
             listen=listen,
             map=map,
             _dispatcher=task_dispatcher,
@@ -84,7 +82,6 @@
             _sockets = sockets
         self.inst = create_server(
             application,
-            {},
             map=map,
             _dispatcher=_dispatcher,
             _start=_start,
@@ -325,7 +322,6 @@
 
             self.inst = create_server(
                 dummy_app,
-                {},
                 map={},
                 _start=_start,
                 _sock=_sock,
@@ -352,7 +348,6 @@
                 _sockets = sockets
             self.inst = create_server(
                 application,
-                {},
                 map=map,
                 _dispatcher=_dispatcher,
                 _start=_start,