diff --git a/src/main.zig b/src/main.zig
index a951667..c32fccb 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -10,7 +10,7 @@ pub fn main() !void {
     const allocator = gpa.allocator();
 
     const address = try net.Address.parseIp("0.0.0.0", 8080);
-    var listener = Listener.init(.{
+    var listener = App.init(.{
         .address = address,
         .allocator = allocator,
         .root_handler = &handleError,
@@ -18,390 +18,403 @@ pub fn main() !void {
     defer listener.deinit();
 
     try listener.router.putRoute("/", &handle);
-    try listener.router.putRoute("/error", &handleError);
-    try listener.router.putRoute("//pee", &handleError);
-    try listener.router.putRoute("/error/*", &handleError);
+    // try listener.router.putRoute("/error", &handleError);
+    // try listener.router.putRoute("//pee", &handleError);
+    // try listener.router.putRoute("/error/*", &handleError);
 
     try listener.listen();
 }
 
-pub fn handle(event: *Listener.Event) anyerror!void {
+pub const App = Listener(DummyContext);
+pub const DummyContext = struct {};
+
+pub fn handle(event: *App.Event) anyerror!void {
     try event.res.body.appendSlice("hello there");
 }
 
-pub fn handleError(event: *Listener.Event) anyerror!void {
+pub fn handleError(event: *App.Event) anyerror!void {
     try event.res.body.appendSlice("ahoy, an error occurred");
 }
 
-pub const Listener = struct {
-    allocator: mem.Allocator,
+pub fn Listener(comptime Context: type) type {
+    return struct {
+        allocator: mem.Allocator,
 
-    /// Listen address
-    address: net.Address,
-    /// Main router
-    router: Router,
-
-    /// Initialization options
-    pub const Options = struct {
+        /// Listen address
         address: net.Address,
-        allocator: mem.Allocator,
-        root_handler: HandlerFn,
-    };
+        /// Main router
+        router: Router,
 
-    pub fn init(options: Options) Listener {
-        return .{
-            .address = options.address,
-            .allocator = options.allocator,
-            .router = Router.init(options.allocator, options.root_handler),
+        /// Initialization options
+        pub const Options = struct {
+            address: net.Address,
+            allocator: mem.Allocator,
+            root_handler: HandlerFn,
         };
-    }
 
-    pub fn deinit(self: *Listener) void {
-        self.router.deinit();
-    }
+        const Self = @This();
 
-    /// Listens for new connections forever
-    pub fn listen(self: *Listener) !void {
-        var arena = heap.ArenaAllocator.init(self.allocator);
-        defer arena.deinit();
-
-        var tcp = try self.address.listen(.{ .reuse_address = true });
-        defer tcp.deinit();
-        std.debug.print("listening at: {any}\n", .{self.address});
-
-        while (true) {
-            const read_buf = try arena.allocator().alloc(u8, 1024 * 32);
-            const connection = try tcp.accept();
-            var server = http.Server.init(connection, read_buf);
-            try self.handle(&server, arena.allocator());
-            _ = arena.reset(.retain_capacity);
-        }
-    }
-
-    fn handle(self: *Listener, server: *http.Server, allocator: mem.Allocator) !void {
-        handler: while (true) {
-            var req = server.receiveHead() catch |e| if (e == error.HttpConnectionClosing) break :handler else return e;
-
-            var event = Event{
-                .req = .{
-                    .uri = try std.Uri.parseWithoutScheme(req.head.target),
-                    .headers = std.ArrayList(*const http.Header).init(allocator),
-                },
-                .res = .{
-                    .status = .ok,
-                    .headers = std.StringHashMap(*http.Header).init(allocator),
-                    .body = std.ArrayList(u8).init(allocator),
-                },
-            };
-
-            var header_it = req.iterateHeaders();
-            while (header_it.next()) |header| try event.req.headers.append(&header);
-
-            try self.router.handle(&event);
-
-            try respondFromEvent(&event, &req, allocator);
-        }
-    }
-
-    fn respondFromEvent(event: *Event, req: *http.Server.Request, allocator: mem.Allocator) !void {
-        const res_body = try event.res.body.toOwnedSlice();
-        const res_headers = try allocator.alloc(http.Header, event.res.headers.count());
-        var i: usize = 0;
-        var header_it = event.res.headers.iterator();
-        while (header_it.next()) |header_ptr| : (i += 1) res_headers[i] = header_ptr.value_ptr.*.*;
-        try req.respond(res_body, .{
-            .status = event.res.status,
-            .extra_headers = res_headers,
-        });
-    }
-
-    /// Single request-response context
-    pub const Event = struct {
-        req: Request,
-        res: Response,
-
-        pub const Request = struct {
-            uri: std.Uri,
-            // head: http.Server.Request.Head,
-            headers: std.ArrayList(*const http.Header),
-        };
-        pub const Response = struct {
-            status: http.Status,
-            headers: std.StringHashMap(*http.Header),
-            body: std.ArrayList(u8),
-        };
-    };
-
-    pub const HandlerFn = *const fn (event: *Event) anyerror!void;
-
-    /// HTTP router
-    /// Some code taken from [unjs/radix3](https://github.com/unjs/radix3)
-    pub const Router = struct {
-        allocator: mem.Allocator,
-        arena: heap.ArenaAllocator,
-
-        root_node: *Node,
-        // static_routes: std.StringHashMap(*Node),
-
-        pub fn init(allocator: mem.Allocator, root_handler: HandlerFn) Router {
-            var arena = heap.ArenaAllocator.init(allocator);
-            var node = Node.init(arena.allocator()) catch @panic("OOM");
-            node.handler = root_handler;
-            // std.debug.print("init router with root_node {any}\n", .{node});
+        pub fn init(options: Options) Self {
             return .{
-                .allocator = allocator,
-                .arena = arena,
-                .root_node = node,
-                // .static_routes = std.StringHashMap(*Node).init(allocator),
+                .address = options.address,
+                .allocator = options.allocator,
+                .router = Router.init(options.allocator, options.root_handler),
             };
         }
 
-        pub fn deinit(self: *Router) void {
-            self.root_node.deinit(self.arena.allocator());
-            self.arena.deinit();
-            // self.static_routes.deinit();
+        pub fn deinit(self: *Self) void {
+            self.router.deinit();
         }
 
-        pub fn handle(self: *Router, event: *Listener.Event) !void {
-            const route = try self.getRoute(event.req.uri.path);
-            try route.handler(event);
+        /// Listens for new connections forever
+        pub fn listen(self: *Self) !void {
+            var arena = heap.ArenaAllocator.init(self.allocator);
+            defer arena.deinit();
+
+            var tcp = try self.address.listen(.{ .reuse_address = true });
+            defer tcp.deinit();
+            std.debug.print("listening at: {any}\n", .{self.address});
+
+            while (true) {
+                const read_buf = try arena.allocator().alloc(u8, 1024 * 32);
+                const connection = try tcp.accept();
+                var server = http.Server.init(connection, read_buf);
+                try self.handle(&server, arena.allocator());
+                _ = arena.reset(.retain_capacity);
+            }
         }
 
-        /// Insert a route if the path is not already present, otherwise overwrite preexisting HandlerFn.
-        pub fn putRoute(self: *Router, path: []const u8, handler: HandlerFn) !void {
-            std.debug.print("\npath {s}\n", .{path});
-            // var is_static_route = true;
-            var sections = mem.splitScalar(u8, path, '/');
-            if (sections.peek()) |sec| if (sec.len == 0) {
-                _ = sections.next();
+        fn handle(self: *Self, server: *http.Server, allocator: mem.Allocator) !void {
+            handler: while (true) {
+                var req = server.receiveHead() catch |e| if (e == error.HttpConnectionClosing) break :handler else return e;
+
+                var ctx = Context{};
+                var event = Event{
+                    .ctx = &ctx,
+                    .req = .{
+                        .uri = try std.Uri.parseWithoutScheme(req.head.target),
+                        .headers = std.ArrayList(*const http.Header).init(allocator),
+                    },
+                    .res = .{
+                        .status = .ok,
+                        .headers = std.StringHashMap(*http.Header).init(allocator),
+                        .body = std.ArrayList(u8).init(allocator),
+                    },
+                };
+
+                var header_it = req.iterateHeaders();
+                while (header_it.next()) |header| try event.req.headers.append(&header);
+
+                const route = try self.router.getRoute(event.req.uri.path);
+                try route.handler(&event);
+
+                try respondFromEvent(&event, &req, allocator);
+            }
+        }
+
+        fn respondFromEvent(event: *Event, req: *http.Server.Request, allocator: mem.Allocator) !void {
+            const res_body = try event.res.body.toOwnedSlice();
+            const res_headers = try allocator.alloc(http.Header, event.res.headers.count());
+            var i: usize = 0;
+            var header_it = event.res.headers.iterator();
+            while (header_it.next()) |header_ptr| : (i += 1) res_headers[i] = header_ptr.value_ptr.*.*;
+            try req.respond(res_body, .{
+                .status = event.res.status,
+                .extra_headers = res_headers,
+            });
+        }
+
+        /// Single request-response context
+        pub const Event = struct {
+            ctx: *Context,
+            req: Request,
+            res: Response,
+
+            pub const Request = struct {
+                uri: std.Uri,
+                // head: http.Server.Request.Head,
+                headers: std.ArrayList(*const http.Header),
             };
-            var node = self.root_node;
-            var unnamed_placeholder_ctr: usize = 0;
-            var matched_nodes = std.ArrayList(*Node).init(self.allocator);
-            defer matched_nodes.deinit();
-            try matched_nodes.append(node);
-            while (sections.next()) |section| {
-                std.debug.print("adding section {s}\n", .{section});
-                if (node.children.get(section)) |child| {
-                    std.debug.print("into child\n", .{});
-                    node = child;
-                } else {
-                    var child_node = try Node.init(self.allocator);
-                    child_node.type = if (mem.startsWith(u8, section, "**"))
-                        .wildcard
-                    else if ((section.len > 0 and section[0] == ':') or mem.eql(u8, section, "*"))
-                        .placeholder
-                    else
-                        .normal;
-                    child_node.parent = node;
-                    // child_node.handler = handler;
-                    try node.children.put(section, child_node);
+            pub const Response = struct {
+                status: http.Status,
+                headers: std.StringHashMap(*http.Header),
+                body: std.ArrayList(u8),
+            };
+        };
 
-                    switch (child_node.type) {
-                        .normal => {},
-                        .wildcard => {
-                            std.debug.print("is wildcard\n", .{});
-                            node.wildcard_child_node = child_node;
-                            child_node.param_name = if (section.len > 3) section[3..] else "_";
-                            // is_static_route = false;
-                        },
-                        .placeholder => {
-                            std.debug.print("is placeholder\n", .{});
-                            child_node.param_name = if (mem.eql(u8, section, "*")) blk: {
-                                std.debug.print("is unnamed placeholder #{d}\n", .{unnamed_placeholder_ctr});
-                                const s = try std.fmt.allocPrint(self.arena.allocator(), "_{d}", .{unnamed_placeholder_ctr}); // TODO: this will leak
-                                unnamed_placeholder_ctr += 1;
-                                break :blk s;
-                            } else try self.arena.allocator().dupe(u8, section[1..]);
-                            try node.placeholder_children.append(child_node);
-                            // is_static_route = false;
-                        },
+        pub const HandlerFn = *const fn (event: *Event) anyerror!void;
+
+        /// HTTP router
+        /// Some code taken from [unjs/radix3](https://github.com/unjs/radix3)
+        pub const Router = struct {
+            allocator: mem.Allocator,
+            arena: heap.ArenaAllocator,
+
+            root_node: *Node,
+            // static_routes: std.StringHashMap(*Node),
+
+            pub fn init(allocator: mem.Allocator, root_handler: HandlerFn) Router {
+                var arena = heap.ArenaAllocator.init(allocator);
+                var node = Node.init(arena.allocator()) catch @panic("OOM");
+                node.handler = root_handler;
+                // std.debug.print("init router with root_node {any}\n", .{node});
+                return .{
+                    .allocator = allocator,
+                    .arena = arena,
+                    .root_node = node,
+                    // .static_routes = std.StringHashMap(*Node).init(allocator),
+                };
+            }
+
+            pub fn deinit(self: *Router) void {
+                self.root_node.deinit(self.arena.allocator(), null);
+                self.arena.deinit();
+                // self.static_routes.deinit();
+            }
+
+            // pub fn handle(self: *Router, event: *Listener.Event) !void {
+            //     const route = try self.getRoute(event.req.uri.path);
+            //     try route.handler(event);
+            // }
+
+            /// Insert a route if the path is not already present, otherwise overwrite preexisting HandlerFn.
+            pub fn putRoute(self: *Router, path: []const u8, handler: HandlerFn) !void {
+                std.debug.print("\npath {s}\n", .{path});
+                // var is_static_route = true;
+                var sections = mem.splitScalar(u8, path, '/');
+                if (sections.peek()) |sec| if (sec.len == 0) {
+                    _ = sections.next();
+                };
+                var node = self.root_node;
+                var unnamed_placeholder_ctr: usize = 0;
+                var matched_nodes = std.ArrayList(*Node).init(self.allocator);
+                defer matched_nodes.deinit();
+                try matched_nodes.append(node);
+                while (sections.next()) |section| {
+                    std.debug.print("adding section {s}\n", .{section});
+                    if (node.children.get(section)) |child| {
+                        std.debug.print("into child\n", .{});
+                        node = child;
+                    } else {
+                        var child_node = try Node.init(self.allocator);
+                        child_node.type = if (mem.startsWith(u8, section, "**"))
+                            .wildcard
+                        else if ((section.len > 0 and section[0] == ':') or mem.eql(u8, section, "*"))
+                            .placeholder
+                        else
+                            .normal;
+                        child_node.parent = node;
+                        // child_node.handler = handler;
+                        try node.children.put(section, child_node);
+
+                        switch (child_node.type) {
+                            .normal => {},
+                            .wildcard => {
+                                std.debug.print("is wildcard\n", .{});
+                                node.wildcard_child_node = child_node;
+                                child_node.param_name = if (section.len > 3) section[3..] else "_";
+                                // is_static_route = false;
+                            },
+                            .placeholder => {
+                                std.debug.print("is placeholder\n", .{});
+                                child_node.param_name = if (mem.eql(u8, section, "*")) blk: {
+                                    std.debug.print("is unnamed placeholder #{d}\n", .{unnamed_placeholder_ctr});
+                                    const s = try std.fmt.allocPrint(self.arena.allocator(), "_{d}", .{unnamed_placeholder_ctr}); // TODO: this will leak
+                                    unnamed_placeholder_ctr += 1;
+                                    break :blk s;
+                                } else try self.arena.allocator().dupe(u8, section[1..]);
+                                try node.placeholder_children.append(child_node);
+                                // is_static_route = false;
+                            },
+                        }
+
+                        // std.debug.print("added child node: {any}\n", .{child_node});
+
+                        try matched_nodes.append(child_node);
+                        node = child_node;
+                    }
+                }
+
+                node.handler = handler;
+
+                // if (is_static_route) std.debug.print("was static route\n", .{});
+
+                // if (is_static_route) try self.static_routes.put(path, node);
+            }
+
+            /// Get the HandlerFn associated with path, otherwise get root_handler.
+            pub fn getRoute(self: *Router, path: []const u8) !*Node {
+                // if (self.static_routes.get(path)) |rt| return rt;
+                std.debug.print("\nget path {s}\n", .{path});
+
+                var params = std.StringHashMap([]const u8).init(self.allocator);
+                defer params.deinit();
+                var params_found = false;
+                var wildcard_node: ?*Node = null;
+                var node: *Node = self.root_node;
+                var wildcard_param: ?[]const u8 = null;
+
+                var remaining = mem.count(u8, path, "/") + 1;
+                var sections = mem.splitScalar(u8, path, '/');
+                if (sections.peek()) |sec| if (sec.len == 0) {
+                    _ = sections.next();
+                };
+                while (sections.next()) |section| : (remaining -= 1) {
+                    std.debug.print("finding section: {s}\n", .{section});
+                    if (node.wildcard_child_node) |wildcard_child_node| {
+                        std.debug.print("section has wildcard\n", .{});
+                        wildcard_node = wildcard_child_node;
+                        wildcard_param = sections.rest();
                     }
 
-                    // std.debug.print("added child node: {any}\n", .{child_node});
-
-                    try matched_nodes.append(child_node);
-                    node = child_node;
-                }
-            }
-
-            node.handler = handler;
-
-            // if (is_static_route) std.debug.print("was static route\n", .{});
-
-            // if (is_static_route) try self.static_routes.put(path, node);
-        }
-
-        /// Get the HandlerFn associated with path, otherwise get root_handler.
-        pub fn getRoute(self: *Router, path: []const u8) !*Node {
-            // if (self.static_routes.get(path)) |rt| return rt;
-            std.debug.print("\nget path {s}\n", .{path});
-
-            var params = std.StringHashMap([]const u8).init(self.allocator);
-            defer params.deinit();
-            var params_found = false;
-            var wildcard_node: ?*Node = null;
-            var node: *Node = self.root_node;
-            var wildcard_param: ?[]const u8 = null;
-
-            var remaining = mem.count(u8, path, "/") + 1;
-            var sections = mem.splitScalar(u8, path, '/');
-            if (sections.peek()) |sec| if (sec.len == 0) {
-                _ = sections.next();
-            };
-            while (sections.next()) |section| : (remaining -= 1) {
-                std.debug.print("finding section: {s}\n", .{section});
-                if (node.wildcard_child_node) |wildcard_child_node| {
-                    std.debug.print("section has wildcard\n", .{});
-                    wildcard_node = wildcard_child_node;
-                    wildcard_param = sections.rest();
-                }
-
-                const next_node = node.children.get(section);
-                if (next_node) |child| {
-                    node = child;
-                    std.debug.print("found section {s} child_node {any}\n", .{ section, child.type });
-                } else {
-                    var child_node: ?*Node = null;
-                    if (node.placeholder_children.items.len > 1) {
-                        // TODO
-                        for (node.placeholder_children.items) |child| place: {
-                            if (child.max_depth == remaining) {
-                                child_node = child;
-                                break :place;
+                    const next_node = node.children.get(section);
+                    if (next_node) |child| {
+                        node = child;
+                        std.debug.print("found section {s} child_node {any}\n", .{ section, child.type });
+                    } else {
+                        var child_node: ?*Node = null;
+                        if (node.placeholder_children.items.len > 1) {
+                            // TODO
+                            for (node.placeholder_children.items) |child| place: {
+                                if (child.max_depth == remaining) {
+                                    child_node = child;
+                                    break :place;
+                                }
                             }
-                        }
-                    } else if (node.placeholder_children.items.len == 1)
-                        child_node = node.placeholder_children.items[0];
+                        } else if (node.placeholder_children.items.len == 1)
+                            child_node = node.placeholder_children.items[0];
 
-                    if (child_node) |n| {
-                        if (n.param_name) |name| try params.put(name, section);
-                        params_found = true;
-                        node = n;
-                    } else break;
+                        if (child_node) |n| {
+                            if (n.param_name) |name| try params.put(name, section);
+                            params_found = true;
+                            node = n;
+                        } else break;
+                    }
                 }
+
+                std.debug.print("ended up with node {any}\nhas wildcard_node: {any}\nis root_node: {any}\n", .{ node.type, wildcard_node != null, node == self.root_node });
+
+                if (wildcard_node) |wildcard| {
+                    node = wildcard;
+                    try params.put("_", wildcard_param.?);
+                    params_found = true;
+                }
+
+                return node;
             }
 
-            std.debug.print("ended up with node {any}\nhas wildcard_node: {any}\nis root_node: {any}\n", .{ node.type, wildcard_node != null, node == self.root_node });
+            /// If there is a route with a matching path, it is deleted from the router, and this function return true. Otherwise it returns false.
+            pub fn removeRoute(self: *Router, path: []const u8) bool {
+                // _ = self.static_routes.remove(path);
+                std.debug.print("\nremoving path {s}\n", .{path});
 
-            if (wildcard_node) |wildcard| {
-                node = wildcard;
-                try params.put("_", wildcard_param.?);
-                params_found = true;
+                var opt_node: ?*Node = self.root_node;
+                var sections = mem.splitScalar(u8, path, '/');
+                if (sections.peek()) |sec| if (sec.len == 0) {
+                    _ = sections.next();
+                };
+                while (sections.next()) |section| {
+                    // TODO: reorder to be safe
+                    std.debug.print("section: {s}\n", .{section});
+                    opt_node = opt_node.?.children.get(section);
+                    if (opt_node == null) return false;
+                }
+                // TODO: should this node.parent be an assert instead?
+                if (opt_node) |node| {
+                    std.debug.print("found node\n", .{});
+                    // if (node.children.count() == 0) {
+                    // std.debug.print("node has no children\n", .{});
+                    if (node.parent) |_| {
+                        std.debug.print("removing self from parent\n", .{});
+                        var rest_sections = mem.splitScalar(u8, path, '/');
+                        var last_section: []const u8 = undefined;
+                        while (rest_sections.peek()) |_| last_section = rest_sections.next().?;
+                        // parent.wildcard_child_node = null;
+                        // parent.placeholder_children.clearAndFree();
+                        // _ = parent.children.remove(last_section); // TODO assert this is true
+                        node.deinit(self.allocator, last_section);
+                    } else node.deinit(self.allocator, null);
+                    // } // else node.deinit(self.allocator);
+                    return true;
+                }
+                return false;
             }
 
-            return node;
-        }
+            pub const Node = struct {
+                type: Type,
+                max_depth: usize, // TODO: what is best here
+                parent: ?*Node = null,
+                children: std.StringHashMap(*Node),
+                handler: HandlerFn,
+                param_name: ?[]const u8 = null,
+                wildcard_child_node: ?*Node = null,
+                placeholder_children: std.ArrayList(*Node),
 
-        /// If there is a route with a matching path, it is deleted from the router, and this function return true. Otherwise it returns false.
-        pub fn removeRoute(self: *Router, path: []const u8) bool {
-            // _ = self.static_routes.remove(path);
-            std.debug.print("\nremoving path {s}\n", .{path});
+                pub const Type = enum { normal, wildcard, placeholder };
 
-            var opt_node: ?*Node = self.root_node;
-            var sections = mem.splitScalar(u8, path, '/');
-            if (sections.peek()) |sec| if (sec.len == 0) {
-                _ = sections.next();
+                /// Expects handler to be set later. Will cause problems otherwise!
+                pub fn init(allocator: mem.Allocator) !*Node {
+                    var self = try allocator.create(Node);
+                    self.type = .normal;
+                    self.max_depth = 256;
+                    self.children = std.StringHashMap(*Node).init(allocator);
+                    self.placeholder_children = std.ArrayList(*Node).init(allocator);
+                    self.parent = null;
+                    self.param_name = null;
+                    self.wildcard_child_node = null;
+                    return self;
+                }
+
+                pub fn deinit(self: *Node, allocator: mem.Allocator, section: ?[]const u8) void {
+                    std.debug.print("deiniting node with {d} children.. and {d} placeholder_children\n", .{ self.children.count(), self.placeholder_children.items.len });
+                    if (section) |sec| if (self.parent) |parent| {
+                        _ = parent.children.remove(sec);
+                    };
+                    for (self.placeholder_children.items) |child| std.debug.print("child {any}\n", .{child}); // child.deinit(allocator);
+                    self.placeholder_children.deinit();
+                    var child_it = self.children.valueIterator();
+                    while (child_it.next()) |child| child.*.deinit(allocator, section);
+                    self.children.deinit();
+                    allocator.destroy(self);
+                }
             };
-            while (sections.next()) |section| {
-                // TODO: reorder to be safe
-                std.debug.print("section: {s}\n", .{section});
-                opt_node = opt_node.?.children.get(section);
-                if (opt_node == null) return false;
-            }
-            // TODO: should this node.parent be an assert instead?
-            if (opt_node) |node| {
-                std.debug.print("found node\n", .{});
-                // if (node.children.count() == 0) {
-                // std.debug.print("node has no children\n", .{});
-                if (node.parent) |_| {
-                    std.debug.print("removing self from parent\n", .{});
-                    var rest_sections = mem.splitScalar(u8, path, '/');
-                    var last_section: []const u8 = undefined;
-                    while (rest_sections.peek()) |_| last_section = rest_sections.next().?;
-                    // parent.wildcard_child_node = null;
-                    // parent.placeholder_children.clearAndFree();
-                    // _ = parent.children.remove(last_section); // TODO assert this is true
-                    node.deinit(self.allocator, last_section);
-                } else node.deinit(self.allocator, null);
-                // } // else node.deinit(self.allocator);
-                return true;
-            }
-            return false;
-        }
-
-        pub const Node = struct {
-            type: Type,
-            max_depth: usize, // TODO: what is best here
-            parent: ?*Node = null,
-            children: std.StringHashMap(*Node),
-            handler: HandlerFn,
-            param_name: ?[]const u8 = null,
-            wildcard_child_node: ?*Node = null,
-            placeholder_children: std.ArrayList(*Node),
-
-            pub const Type = enum { normal, wildcard, placeholder };
-
-            /// Expects handler to be set later. Will cause problems otherwise!
-            pub fn init(allocator: mem.Allocator) !*Node {
-                var self = try allocator.create(Node);
-                self.type = .normal;
-                self.max_depth = 256;
-                self.children = std.StringHashMap(*Node).init(allocator);
-                self.placeholder_children = std.ArrayList(*Node).init(allocator);
-                self.parent = null;
-                self.param_name = null;
-                self.wildcard_child_node = null;
-                return self;
-            }
-
-            pub fn deinit(self: *Node, allocator: mem.Allocator, section: ?[]const u8) void {
-                std.debug.print("deiniting node with {d} children.. and {d} placeholder_children\n", .{ self.children.count(), self.placeholder_children.items.len });
-                if (section) |sec| if (self.parent) |parent| parent.children.remove(sec);
-                for (self.placeholder_children.items) |child| std.debug.print("child {any}\n", .{child}); // child.deinit(allocator);
-                self.placeholder_children.deinit();
-                var child_it = self.children.valueIterator();
-                while (child_it.next()) |child| child.*.deinit(allocator);
-                self.children.deinit();
-                allocator.destroy(self);
-            }
         };
     };
-};
-
-test "Router" {
-    var router = Listener.Router.init(std.testing.allocator, &dummyHandler);
-    defer router.deinit();
-
-    try router.putRoute("/foo", &hummyDandler);
-    try router.putRoute("/foo/bar", &hummyDandler);
-    try router.putRoute("/foo/foobar", &tummyCandler);
-    try router.putRoute("/bar", &hummyDandler);
-
-    try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/")).handler);
-    try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/foo")).handler);
-    try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/foo/bar")).handler);
-    try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/foobar")).handler);
-    try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/bar")).handler);
-
-    try std.testing.expect(router.removeRoute("/foo"));
-
-    try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/foo/bar")).handler);
-    try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/foo")).handler);
-    try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/")).handler);
-
-    try router.putRoute("/foo", &hummyDandler);
-    try router.putRoute("/foo/**", &tummyCandler);
-    try router.putRoute("/bar/*", &tummyCandler);
-
-    try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/foo")).handler);
-    try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/bar")).handler);
-    try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/bar/foo")).handler);
-    try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/foof")).handler);
-
-    try std.testing.expect(router.removeRoute("/bar/*"));
 }
 
-fn dummyHandler(_: *Listener.Event) anyerror!void {}
-fn hummyDandler(_: *Listener.Event) anyerror!void {}
-fn tummyCandler(_: *Listener.Event) anyerror!void {}
+// test "Router" {
+//     var router = Listener.Router.init(std.testing.allocator, &dummyHandler);
+//     defer router.deinit();
+
+//     try router.putRoute("/foo", &hummyDandler);
+//     try router.putRoute("/foo/bar", &hummyDandler);
+//     try router.putRoute("/foo/foobar", &tummyCandler);
+//     try router.putRoute("/bar", &hummyDandler);
+
+//     try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/")).handler);
+//     try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/foo")).handler);
+//     try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/foo/bar")).handler);
+//     try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/foobar")).handler);
+//     try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/bar")).handler);
+
+//     try std.testing.expect(router.removeRoute("/foo"));
+
+//     try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/foo/bar")).handler);
+//     try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/foo")).handler);
+//     try std.testing.expectEqual(&dummyHandler, (try router.getRoute("/")).handler);
+
+//     try router.putRoute("/foo", &hummyDandler);
+//     try router.putRoute("/foo/**", &tummyCandler);
+//     try router.putRoute("/bar/*", &tummyCandler);
+
+//     try std.testing.expectEqual(&hummyDandler, (try router.getRoute("/foo")).handler);
+//     try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/bar")).handler);
+//     try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/bar/foo")).handler);
+//     try std.testing.expectEqual(&tummyCandler, (try router.getRoute("/foo/foof")).handler);
+
+//     try std.testing.expect(router.removeRoute("/bar/*"));
+// }
+
+// fn dummyHandler(_: *Listener.Event) anyerror!void {}
+// fn hummyDandler(_: *Listener.Event) anyerror!void {}
+// fn tummyCandler(_: *Listener.Event) anyerror!void {}