OK, overall looks like this'll definitely do the trick. As a lisp aficionado, I think you could remove a lot of the state and coupling here, though. Here's what I would do:

1. Get rid of all the state checks and just initialize all the state right at the beginning (kill assureUrlInited and assureConfigInited -- more associated changes to enable that described later).
1. Use event queues to tell any interested classes about proxies (Events.asyncEventBus().post(newConfig);).
1. The above will allow you to decouple this class from all other classes -- you can just pass S3Config objects as events when they change
1. Just store the S3Config in Model. To avoid blocking on the S3 config network lookup right at startup, I would just thread it and make the whole thing slightly lazy, i.e. when you get a new config, send it out in a new event and save the S3Config in Model for the next run. That would also mean removing the S3Config-dependent stuff from LanternClientConstants and just putting it in Model (let the S3Config object replace those constants).

That approach overall would enable a couple of things that I think would be nice:

1. DefaultProxyTracker and ModelIo would no longer need to know about S3ConfigManager, just S3Config events
1. You wouldn't have to worry about any state in S3ConfigManager (just initialize the URL as soon as the class is constructed and thread the network lookup, but with the network lookup not setting any state in this class, just producing events).
1. Even LanternModule could remove DefaultProxyTracker

I'd be happy to code up some of the above proposed patch as well. What do you think?