package ${package};

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.place.shared.PlaceHistoryHandler.DefaultHistorian;
import com.google.gwt.place.shared.PlaceHistoryHandler.Historian;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.web.bindery.autobean.gwt.client.impl.JsoSplittable;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanCodex;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.SimpleEventBus;
import com.google.web.bindery.requestfactory.shared.RequestTransport;

import dagger.Binds;
import dagger.Module;
import dagger.Provides;

import javax.inject.Singleton;

@Module
public abstract class ${module}Module {

	private static Place getDefaultPlace() {
		return new HomePlace();
	}

	@Provides @Singleton
	static SimpleEventBus provideSimpleEventBus() {
		return new SimpleEventBus();
	}

	@Binds
	abstract EventBus provideEventBus(SimpleEventBus bus);

	@Provides
	static PlaceHistoryMapper providePlaceHistoryMapper() {
		return GWT.create(${module}PlaceHistoryMapper.class);
	}

	@Provides
	static Historian provideHistorian() {
		// For best UX at login time (preserving place), use an Html5History: https://gist.github.com/1883821
		return new DefaultHistorian();
	}

	@Provides
	static RequestTransport provideRequestTransport() {
		return new AuthAwareRequestTransport();
	}

	@Provides @Singleton
	static PlaceController providePlaceController(EventBus eventBus) {
		return new PlaceController(eventBus);
	}

	@Provides @Singleton
	static PlaceHistoryHandler providePlaceHistoryHandler(PlaceHistoryMapper mapper, Historian historian,
			PlaceController controller, EventBus eventBus) {
		PlaceHistoryHandler handler = new PlaceHistoryHandler(mapper, historian);
		handler.register(controller, eventBus, getDefaultPlace());
		return handler;
	}

	@Provides @Singleton
	static ${module}Factory provide${module}Factory(EventBus eventBus, RequestTransport transport) {
		${module}Factory factory = GWT.create(${module}Factory.class);
		factory.initialize(eventBus, transport);
		return factory;
	}

	@Provides
	static Scheduler provideScheduler() {
		return Scheduler.get();
	}

	@Provides @LogoutUrl
	static native String provideLogoutUrl() /*-{
		return $wnd.logoutUrl != null ? String($wnd.logoutUrl) : null;
	}-*/;

	@Provides @CurrentUser @Singleton
	static User provideCurrentUser() {
		final User.Factory factory = GWT.create(User.Factory.class);
		final JavaScriptObject nativeUser = getNativeUser();
		final AutoBean<User> user;
		if (GWT.isScript()) {
			user = AutoBeanCodex.decode(factory, User.class, (JsoSplittable) nativeUser);
		} else {
			// JsoSplittable is a @GwtScriptOnly, so we need this hack in devMode
			final String payload = new JSONObject(nativeUser).toString();
			user = AutoBeanCodex.decode(factory, User.class, payload);
		}
		return user.as();
	}

	@Provides @CurrentUser
	static String provideUserName(@CurrentUser User user) {
		return user.getUserName();
	}

	@Provides @IsAdmin
	static boolean provideIsAdmin(@CurrentUser User user) {
		return user.isAdmin();
	}

	private static native JavaScriptObject getNativeUser() /*-{
		return $wnd.user;
	}-*/;
}

@@ -91,115 +91,17 @@
 ent.
-JavaScriptObject;%0Aimport com.google.gwt.core.client.Scheduler;%0Aimport com.google.gwt.json.client.JSONObject
+Scheduler
 ;%0Aim
@@ -516,64 +516,8 @@
 le;%0A
-import com.google.web.bindery.autobean.shared.AutoBean;%0A
 impo
@@ -824,16 +824,98 @@
 vides;%0A%0A
+import jsinterop.annotations.JsPackage;%0Aimport jsinterop.annotations.JsProperty;%0A%0A
 import j
@@ -2486,123 +2486,110 @@
 rl%0A%09
-static native String provideLogoutUrl() /*-%7B%0A%09%09return $wnd.logoutUrl != null ? String($wnd.logoutUrl) : null;%0A%09%7D-*/
+@JsProperty(name = %22logoutUrl%22, namespace = JsPackage.GLOBAL)%0A%09static native String provideLogoutUrl()
 ;%0A%0A%09
@@ -2727,423 +2727,73 @@
 ;%0A%09%09
-final JavaScriptObject nativeUser = getNativeUser();%0A%09%09final AutoBean%3CUser%3E user;%0A%09%09if (GWT.isScript()) %7B%0A%09%09%09user = AutoBeanCodex.decode(factory, User.class, (JsoSplittable) nativeUser);%0A%09%09%7D else %7B%0A%09%09%09// JsoSplittable is a @GwtScriptOnly, so we need this hack in devMode%0A%09%09%09final String payload = new JSONObject(nativeUser).toString();%0A%09%09%09user = AutoBeanCodex.decode(factory, User.class, payload);%0A%09%09%7D%0A%09%09return user
+return AutoBeanCodex.decode(factory, User.class, getNativeUser())
 .as(
@@ -3019,16 +3019,74 @@
 ();%0A%09%7D%0A%0A
+%09@JsProperty(name = %22user%22, namespace = JsPackage.GLOBAL)%0A
 %09private
@@ -3105,23 +3105,20 @@
 ve J
-avaScriptObject
+soSplittable
  get
@@ -3133,39 +3133,8 @@
 er()
- /*-%7B%0A%09%09return $wnd.user;%0A%09%7D-*/
 ;%0A%7D%0A

Replace JSNI with JsInterop