public static CAresChannel CAresChannel(this Loop loop)
		{
			Dictionary<int, Poll> dict = new Dictionary<int, Poll>();
			
			var dns = new CAresChannel(new CAresChannelOptions() {
				SocketCallback = (channel, socket, read, write) => {
					if (read | write) {
						var poll = new Poll(loop, socket);
						poll.Event += (@event) => channel.Process(socket, -1);
						poll.Start(PollEvent.Read);
						dict[socket] = poll;
					} else {
						var poll = dict[socket];
						poll.Close();
						dict.Remove(socket);
					}
				}
			});
			return dns;
		}
		static void BaseRun(Container container, Action run)
		{
			Debug.Log("Application Start");

			Debug.Log("Application ThreadId: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
			try {
				container = new ApplicationContainer(container);

				if (Loop == null) {
					throw new Exception("You have to initialize the application with a context");
				}

				if (container.CanFocus) {
					container.HasFocus = true;
				}

				// draw everything and refresh curses
				Debug.Log("Terminal width: {0} Terminal height: {1}", Curses.Terminal.Width, Curses.Terminal.Height);
				container.SetDim(0, 0, Curses.Terminal.Width, Curses.Terminal.Height);

				container.Redraw();
				container.SetCursorPosition();
				Curses.Refresh();

				keyaction = (key) => {
					if (key == QuitKey) {
						Exit();
					} else if (key == -2) {
						container.Redraw();
						container.SetCursorPosition();
						Curses.Refresh();
					} else if (key == Curses.Key.Resize) {
						container.SetDim(0, 0, Curses.Terminal.Width, Curses.Terminal.Height);
						container.ProcessKey(Curses.Key.Resize);
						container.ForceRedraw();
						container.SetCursorPosition();
						container.Invalid = true;
						Curses.Refresh();
					} else {
						container.ProcessKey(key);
					}
				};

				signalWatcher = new SignalWatcher(Loop, Signum.SIGWINCH , () => {
					Curses.resizeterm(Console.WindowHeight, Console.WindowWidth);
					keyaction(Curses.Key.Resize);
				});
				signalWatcher.Start();

				stdin = new Poll(Loop, 0);
				stdin.Event += (_) => {
					keyaction(Curses.getch());
				};
				stdin.Start(PollEvent.Read);

				prepare = new Prepare();
				prepare.Start(() => {
					if (container.Invalid) {
						keyaction(-2);
					}
				});

				if (colors != null) {
					Curses.Terminal.SetColors(colors);
				}

				run?.Invoke();

				OnEnd();
			} finally {
				Window.End();
				Running = false;

				Loop = null;
				Debug.Log("Application End");
			}
		}