import io.datakernel.async.Promise;
import io.datakernel.config.Config;
import io.datakernel.di.annotation.Inject;
import io.datakernel.di.annotation.Named;
import io.datakernel.di.annotation.Provides;
import io.datakernel.di.core.Binding;
import io.datakernel.di.core.Key;
import io.datakernel.di.module.AbstractModule;
import io.datakernel.di.module.Module;
import io.datakernel.eventloop.Eventloop;
import io.datakernel.http.AsyncHttpServer;
import io.datakernel.http.HttpResponse;
import io.datakernel.launcher.Launcher;
import io.datakernel.service.ServiceGraphModule;

import static io.datakernel.config.ConfigConverters.ofInteger;

//[START EXAMPLE]
public class ModuleRebindExample extends Launcher {
	@Inject
	@Named("server1")
	AsyncHttpServer server1;

	@Inject
	@Named("server2")
	AsyncHttpServer server2;

	static class ServerModule extends AbstractModule {
		@Provides
		AsyncHttpServer server(Eventloop eventloop, Config config) {
			return AsyncHttpServer.create(eventloop,
					request -> Promise.of(
							HttpResponse.ok200().withPlainText(config.get("message"))))
					.withListenPort(config.get(ofInteger(), "port"));
		}
	}

	@Override
	protected Module getModule() {
		return Module.create()
				.install(ServiceGraphModule.create())
				.install(new ServerModule()
						.rebindImport(Config.class, Binding.to(cfg -> cfg.getChild("modules.1"), Config.class))
						.rebindExport(AsyncHttpServer.class, Key.of(AsyncHttpServer.class, "server1")))
				.install(new ServerModule()
						.rebindImport(Config.class, Binding.to(cfg -> cfg.getChild("modules.2"), Config.class))
						.rebindExport(AsyncHttpServer.class, Key.of(AsyncHttpServer.class, "server2")))
				.bind(Eventloop.class).to(Eventloop::create)
				.bind(Config.class).toInstance(
						Config.create()
								.with("modules.1.port", "8080")
								.with("modules.1.message", 	"Hello from Server 1")
								.with("modules.2.port", "8081")
								.with("modules.2.message", "Hello from Server 2"));
	}

	@Override
	protected void run() throws InterruptedException {
		System.out.println("Server1: http://127.0.0.1:8080/ \nServer2: http://127.0.0.1:8081/");
		awaitShutdown();
	}

	public static void main(String[] args) throws Exception {
		ModuleRebindExample example = new ModuleRebindExample();
		example.launch(args);
	}
	//[END EXAMPLE]
}

@@ -65,16 +65,59 @@
 Config;%0A
+import io.datakernel.di.annotation.Export;%0A
 import i
@@ -242,46 +242,8 @@
 es;%0A
-import io.datakernel.di.core.Binding;%0A
 impo
@@ -439,24 +439,64 @@
 HttpServer;%0A
+import io.datakernel.http.AsyncServlet;%0A
 import io.da
@@ -675,16 +675,64 @@
 Integer;
+%0Aimport static io.datakernel.di.core.Binding.to;
 %0A%0A//%5BSTA
@@ -980,113 +980,94 @@
 sync
-Http
 Serv
-er
+let
  serv
-er(Eventloop eventloop, Config config) %7B%0A%09%09%09return AsyncHttpServer.create(eventloop,%0A%09%09%09%09%09
+let(Config config) %7B%0A%09%09%09String message = config.get(%22message%22);%0A%09%09%09return 
 requ
@@ -1085,18 +1085,16 @@
 ise.of(%0A
-%09%09
 %09%09%09%09%09Htt
@@ -1129,31 +1129,182 @@
 ext(
-config.get(%22message%22)))
+message));%0A%09%09%7D%0A%0A%09%09@Provides%0A%09%09@Export%0A%09%09AsyncHttpServer server(Eventloop eventloop, AsyncServlet servlet, Config config) %7B%0A%09%09%09return AsyncHttpServer.create(eventloop, servlet
 )%0A%09%09
@@ -1540,36 +1540,42 @@
 .class, 
-Binding.to(cfg -%3E cf
+to(rootConfig -%3E rootConfi
 g.getChi
@@ -1578,24 +1578,22 @@
 tChild(%22
-modules.
+config
 1%22), Con
@@ -1760,28 +1760,34 @@
 ss, 
-Binding.to(cfg -%3E cf
+to(rootConfig -%3E rootConfi
 g.ge
@@ -1794,24 +1794,22 @@
 tChild(%22
-modules.
+config
 2%22), Con
@@ -2028,24 +2028,22 @@
 %09.with(%22
-modules.
+config
 1.port%22,
@@ -2066,24 +2066,22 @@
 %09.with(%22
-modules.
+config
 1.messag
@@ -2084,17 +2084,16 @@
 ssage%22, 
-%09
 %22Hello f
@@ -2122,24 +2122,22 @@
 %09.with(%22
-modules.
+config
 2.port%22,
@@ -2164,16 +2164,14 @@
 th(%22
-modules.
+config
 2.me
@@ -2296,74 +2296,165 @@
 ln(%22
-Server1: http://127.0.0.1:8080/ %5CnServer2: http://127.0.0.1:8081/%22
+http://localhost:%22 + server1.getListenAddresses().get(0).getPort());%0A%09%09System.out.println(%22http://localhost:%22 + server2.getListenAddresses().get(0).getPort()
 );%0A%09

Improve ModuleRebindExample