protected void addOnLoaded(Handler<T> doneHandler) {
		//once loaded is true, it will never go back to false.
		//even if double checked locking fails and we incorrectly go into the synchronized block,
		//no harm will be done because by the end, we'll see that loaded is in fact true.
		//thus, double checked locking enables us to safely avoid synchronization when possible.
		boolean loaded = this.loaded;
		if (!loaded) {
			synchronized (monitor) {
				loaded = this.loaded;
				if (!loaded)
					listeners.add(doneHandler);
			}
		}
		if (loaded)
			if (success)
				doneHandler.handle(self);
			else
				doneHandler.handle(null);
	}