final Set<Key> overriddenKeys = Sets.newHashSet();
final Set<Class<? extends Annotation>> overridesScopeAnnotations = Sets.newHashSet();
// execute the overrides module, keeping track of which keys and scopes are bound
new ModuleWriter() {
@Override public <T> void writeBind(Binder binder, Binding<T> binding) {
overriddenKeys.add(binding.getKey());
super.writeBind(binder, binding);
}
@Override public void writeBindScope(Binder binder, ScopeBinding element) {
overridesScopeAnnotations.add(element.getAnnotationType());
super.writeBindScope(binder, element);
}
}.apply(binder(), overrideElements);
// execute the original module, skipping all scopes and overridden keys. We only skip each
// overridden binding once so things still blow up if the module binds the same thing
// multiple times.
final Map<Scope, Object> scopeInstancesInUse = Maps.newHashMap();
final List<ScopeBinding> scopeBindings = Lists.newArrayList();
new ModuleWriter() {
@Override public <T> void writeBind(Binder binder, final Binding<T> binding) {
if (!overriddenKeys.remove(binding.getKey())) {
super.writeBind(binder, binding);
// Record when a scope instance is used in a binding
Scope scope = getScopeInstanceOrNull(binding);
if (scope != null) {
scopeInstancesInUse.put(scope, binding.getSource());
}
}
}
@Override public void writeBindScope(Binder binder, ScopeBinding element) {
scopeBindings.add(element);
}
}.apply(binder(), elements);
// execute the scope bindings, skipping scopes that have been overridden. Any scope that
// is overridden and in active use will prompt an error
new ModuleWriter() {
@Override public void writeBindScope(Binder binder, ScopeBinding element) {
if (!overridesScopeAnnotations.remove(element.getAnnotationType())) {
super.writeBindScope(binder, element);
} else {
Object source = scopeInstancesInUse.get(element.getScope());