This CL changes how singletons are loaded. Previously we registered a callback at bind-time. Now we keep track of whether bindings were eager (using the new enum LoadStrategy) and we load 'em all afterwards.

git-svn-id: https://google-guice.googlecode.com/svn/trunk@498 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/BindCommandProcessor.java b/src/com/google/inject/BindCommandProcessor.java
index 008f6c8..f1fab1e 100644
--- a/src/com/google/inject/BindCommandProcessor.java
+++ b/src/com/google/inject/BindCommandProcessor.java
@@ -20,7 +20,10 @@
 import com.google.inject.commands.BindConstantCommand;
 import com.google.inject.commands.BindScoping;
 import com.google.inject.commands.BindTarget;
-import com.google.inject.internal.*;
+import com.google.inject.internal.Annotations;
+import com.google.inject.internal.ErrorMessages;
+import com.google.inject.internal.ResolveFailedException;
+import com.google.inject.internal.StackTraceElements;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
@@ -38,8 +41,6 @@
   private final Map<Class<? extends Annotation>, Scope> scopes;
   private final List<CreationListener> creationListeners
       = new ArrayList<CreationListener>();
-  private final List<ContextualCallable<Void>> eagerSingletonCreators
-      = new ArrayList<ContextualCallable<Void>>();
   private final Stage stage;
   private final Map<Key<?>, BindingImpl<?>> bindings;
   private final Map<Object, Void> outstandingInjections;
@@ -71,8 +72,9 @@
 
     validateKey(command.getSource(), command.getKey());
 
-    // TODO(jessewilson): Scope annotation on type, like @Singleton
-    final boolean shouldPreload = command.getScoping().isEagerSingleton();
+    final LoadStrategy loadStrategy = command.getScoping().isEagerSingleton()
+        ? LoadStrategy.EAGER
+        : LoadStrategy.LAZY;
     final Scope scope = command.getScoping().acceptVisitor(new BindScoping.Visitor<Scope>() {
       public Scope visitEagerSingleton() {
         return Scopes.SINGLETON;
@@ -104,8 +106,8 @@
         outstandingInjections.put(instance, null);
         InternalFactory<? extends T> scopedFactory
             = Scopes.scope(key, injector, factory, scope);
-        createBinding(source, shouldPreload, new InstanceBindingImpl<T>(
-            injector, key, source, scopedFactory, instance));
+        putBinding(new InstanceBindingImpl<T>(
+                injector, key, source, scopedFactory, instance));
         return null;
       }
 
@@ -115,8 +117,8 @@
         outstandingInjections.put(provider, null);
         InternalFactory<? extends T> scopedFactory
             = Scopes.scope(key, injector, factory, scope);
-        createBinding(source, shouldPreload, new ProviderInstanceBindingImpl<T>(
-            injector, key, source, scopedFactory, scope, provider));
+        putBinding(new ProviderInstanceBindingImpl<T>(
+                injector, key, source, scopedFactory, scope, provider, loadStrategy));
         return null;
       }
 
@@ -126,8 +128,8 @@
         creationListeners.add(boundProviderFactory);
         InternalFactory<? extends T> scopedFactory = Scopes.scope(
             key, injector, (InternalFactory<? extends T>) boundProviderFactory, scope);
-        createBinding(source, shouldPreload, new LinkedProviderBindingImpl<T>(
-            injector, key, source, scopedFactory, scope, providerKey));
+        putBinding(new LinkedProviderBindingImpl<T>(
+                injector, key, source, scopedFactory, scope, providerKey, loadStrategy));
         return null;
       }
 
@@ -140,8 +142,8 @@
         creationListeners.add(factory);
         InternalFactory<? extends T> scopedFactory
             = Scopes.scope(key, injector, factory, scope);
-        createBinding(source, shouldPreload, new LinkedBindingImpl<T>(
-            injector, key, source, scopedFactory, scope, targetKey));
+        putBinding(new LinkedBindingImpl<T>(
+                injector, key, source, scopedFactory, scope, targetKey, loadStrategy));
         return null;
       }
 
@@ -154,7 +156,7 @@
         // @ImplementedBy annotation or something.
         if (key.hasAnnotationType() || !(type instanceof Class<?>)) {
           addError(source, ErrorMessages.MISSING_IMPLEMENTATION);
-          createBinding(source, shouldPreload, invalidBinding(injector, key, source));
+          putBinding(invalidBinding(injector, key, source));
           return null;
         }
 
@@ -163,11 +165,11 @@
         Class<T> clazz = (Class<T>) type;
         final BindingImpl<T> binding;
         try {
-          binding = injector.createUnitializedBinding(clazz, scope, source);
-          createBinding(source, shouldPreload, binding);
+          binding = injector.createUnitializedBinding(clazz, scope, source, loadStrategy);
+          putBinding(binding);
         } catch (ResolveFailedException e) {
           injector.errorHandler.handle(source, e.getMessage());
-          createBinding(source, shouldPreload, invalidBinding(injector, key, source));
+          putBinding(invalidBinding(injector, key, source));
           return null;
         }
 
@@ -224,31 +226,33 @@
     return true;
   }
 
-  private <T> void createBinding(Object source, boolean shouldPreload,
-      BindingImpl<T> binding) {
-    putBinding(binding);
-
-    // Register to preload if necessary.
-    if (binding.getScope() == Scopes.SINGLETON) {
-      if (stage == Stage.PRODUCTION || shouldPreload) {
-        eagerSingletonCreators.add(new EagerSingletonCreator(binding.key, binding.internalFactory));
-      }
-    } else {
-      if (shouldPreload) {
-        addError(source, ErrorMessages.PRELOAD_NOT_ALLOWED);
-      }
-    }
-  }
-
   public void createUntargettedBindings() {
     for (Runnable untargettedBinding : untargettedBindings) {
       untargettedBinding.run();
     }
   }
 
-  public void createEagerSingletons(InjectorImpl injector) {
-    for (ContextualCallable<Void> preloader : eagerSingletonCreators) {
-      injector.callInContext(preloader);
+  public void loadEagerSingletons(InjectorImpl injector) {
+    // load eager singletons, or all singletons if we're in Stage.PRODUCTION.
+    for (final BindingImpl<?> binding : bindings.values()) {
+      if (stage == Stage.PRODUCTION || binding.getLoadStrategy() == LoadStrategy.EAGER) {
+        injector.callInContext(new ContextualCallable<Void>() {
+          public Void call(InternalContext context) {
+            InjectionPoint<?> injectionPoint
+                = InjectionPoint.newInstance(binding.key, context.getInjector());
+            context.setInjectionPoint(injectionPoint);
+            try {
+              binding.internalFactory.get(context, injectionPoint);
+              return null;
+            } catch(ProvisionException provisionException) {
+              provisionException.addContext(injectionPoint);
+              throw provisionException;
+            } finally {
+              context.setInjectionPoint(null);
+            }
+          }
+        });
+      }
     }
   }
 
@@ -258,31 +262,6 @@
     }
   }
 
-  private static class EagerSingletonCreator implements ContextualCallable<Void> {
-    private final Key<?> key;
-    private final InternalFactory<?> factory;
-
-    public EagerSingletonCreator(Key<?> key, InternalFactory<?> factory) {
-      this.key = key;
-      this.factory = Objects.nonNull(factory, "factory");
-    }
-
-    public Void call(InternalContext context) {
-      InjectionPoint<?> injectionPoint
-          = InjectionPoint.newInstance(key, context.getInjector());
-      context.setInjectionPoint(injectionPoint);
-      try {
-        factory.get(context, injectionPoint);
-        return null;
-      } catch(ProvisionException provisionException) {
-        provisionException.addContext(injectionPoint);
-        throw provisionException;
-      } finally {
-        context.setInjectionPoint(null);
-      }
-    }
-  }
-
   private void putBinding(BindingImpl<?> binding) {
     Key<?> key = binding.getKey();
     Binding<?> original = bindings.get(key);
diff --git a/src/com/google/inject/BindingImpl.java b/src/com/google/inject/BindingImpl.java
index 771d13d..ce6e955 100644
--- a/src/com/google/inject/BindingImpl.java
+++ b/src/com/google/inject/BindingImpl.java
@@ -30,14 +30,16 @@
   final Object source;
   final InternalFactory<? extends T> internalFactory;
   final Scope scope;
+  final LoadStrategy loadStrategy;
 
   BindingImpl(InjectorImpl injector, Key<T> key, Object source,
-      InternalFactory<? extends T> internalFactory, Scope scope) {
+      InternalFactory<? extends T> internalFactory, Scope scope, LoadStrategy loadStrategy) {
     this.injector = injector;
     this.key = key;
     this.source = source;
     this.internalFactory = internalFactory;
     this.scope = scope;
+    this.loadStrategy = loadStrategy;
   }
 
   public Key<T> getKey() {
@@ -80,6 +82,10 @@
     return internalFactory instanceof ConstantFactory<?>;
   }
 
+  LoadStrategy getLoadStrategy() {
+    return loadStrategy;
+  }
+
   /**
    * Perform any post-creation initialization, that could require construction
    * of other bindings.
diff --git a/src/com/google/inject/ClassBindingImpl.java b/src/com/google/inject/ClassBindingImpl.java
index 36fb272..10a1d03 100644
--- a/src/com/google/inject/ClassBindingImpl.java
+++ b/src/com/google/inject/ClassBindingImpl.java
@@ -36,8 +36,9 @@
 
   ClassBindingImpl(InjectorImpl injector, Key<T> key, Object source,
       InternalFactory<? extends T> internalFactory, Scope scope,
-      InjectorImpl.LateBoundConstructor<T> lateBoundConstructor) {
-    super(injector, key, source, internalFactory, scope);
+      InjectorImpl.LateBoundConstructor<T> lateBoundConstructor,
+      LoadStrategy loadStrategy) {
+    super(injector, key, source, internalFactory, scope, loadStrategy);
     this.lateBoundConstructor = lateBoundConstructor;
   }
 
diff --git a/src/com/google/inject/ConstantBindingImpl.java b/src/com/google/inject/ConstantBindingImpl.java
index 7ff5aa9..b6d9c4f 100644
--- a/src/com/google/inject/ConstantBindingImpl.java
+++ b/src/com/google/inject/ConstantBindingImpl.java
@@ -33,13 +33,12 @@
 
   ConstantBindingImpl(InjectorImpl injector, Key<T> key, Object source,
       InternalFactory<T> internalFactory, T value) {
-    super(injector, key, source, internalFactory, Scopes.NO_SCOPE);
+    super(injector, key, source, internalFactory, Scopes.NO_SCOPE, LoadStrategy.LAZY);
     this.value = value;
     this.provider = Providers.of(value);
   }
 
-  @Override
-  public Provider<T> getProvider() {
+  @Override public Provider<T> getProvider() {
     return this.provider;
   }
 
@@ -51,8 +50,7 @@
     return this.value;
   }
 
-  @Override
-  public String toString() {
+  @Override public String toString() {
     return new ToStringBuilder(ConstantBinding.class)
         .add("key", key)
         .add("value", value)
diff --git a/src/com/google/inject/InjectorBuilder.java b/src/com/google/inject/InjectorBuilder.java
index 6bd907a..39e23a1 100644
--- a/src/com/google/inject/InjectorBuilder.java
+++ b/src/com/google/inject/InjectorBuilder.java
@@ -187,7 +187,7 @@
     injector.fulfillOutstandingInjections();
     stopwatch.resetAndLog("Instance injection");
 
-    bindCommandProcesor.createEagerSingletons(injector);
+    bindCommandProcesor.loadEagerSingletons(injector);
     stopwatch.resetAndLog("Preloading");
   }
 
@@ -241,7 +241,7 @@
     injector.explicitBindings.put(key,
         new ProviderInstanceBindingImpl<Logger>(injector, key,
             SourceProviders.UNKNOWN_SOURCE, loggerFactory, Scopes.NO_SCOPE,
-            loggerFactory));
+            loggerFactory, LoadStrategy.LAZY));
   }
 
   static class LoggerFactory implements InternalFactory<Logger>, Provider<Logger> {
diff --git a/src/com/google/inject/InjectorImpl.java b/src/com/google/inject/InjectorImpl.java
index 2731361..82e3cc4 100644
--- a/src/com/google/inject/InjectorImpl.java
+++ b/src/com/google/inject/InjectorImpl.java
@@ -190,7 +190,8 @@
               new InternalFactoryToProviderAdapter(binding.getProvider(),
                   binding.getSource()),
               Scopes.NO_SCOPE,
-              binding.getProvider());
+              binding.getProvider(),
+              LoadStrategy.LAZY);
         } else {
           bindingImpl = null;
         }
@@ -250,7 +251,7 @@
    * from Binding<T>.
    */
   private <T> BindingImpl<Provider<T>> createProviderBinding(
-      Key<Provider<T>> key) throws ResolveFailedException {
+      Key<Provider<T>> key, LoadStrategy loadStrategy) throws ResolveFailedException {
     Type providerType = key.getTypeLiteral().getType();
 
     // If the Provider has no type parameter (raw Provider)...
@@ -265,7 +266,7 @@
     @SuppressWarnings("unchecked")
     Key<T> providedKey = (Key<T>) key.ofType(entryType);
 
-    return new ProviderBindingImpl<T>(this, key, getBindingOrThrow(providedKey));
+    return new ProviderBindingImpl<T>(this, key, getBindingOrThrow(providedKey), loadStrategy);
   }
 
   void handleMissingBinding(Object source, Key<?> key) {
@@ -290,9 +291,9 @@
     final Binding<T> providedBinding;
 
     ProviderBindingImpl(InjectorImpl injector, Key<Provider<T>> key,
-        Binding<T> providedBinding) {
+        Binding<T> providedBinding, LoadStrategy loadStrategy) {
       super(injector, key, SourceProviders.UNKNOWN_SOURCE,
-          createInternalFactory(providedBinding), Scopes.NO_SCOPE);
+          createInternalFactory(providedBinding), Scopes.NO_SCOPE, loadStrategy);
       this.providedBinding = providedBinding;
     }
 
@@ -403,7 +404,7 @@
     ConvertedConstantBindingImpl(InjectorImpl injector, Key<T> key, T value,
         Binding<String> originalBinding) {
       super(injector, key, SourceProviders.UNKNOWN_SOURCE,
-          new ConstantFactory<T>(value), Scopes.NO_SCOPE);
+          new ConstantFactory<T>(value), Scopes.NO_SCOPE, LoadStrategy.LAZY);
       this.value = value;
       this.provider = Providers.of(value);
       this.originalBinding = originalBinding;
@@ -436,14 +437,10 @@
     }
   }
 
-  <T> BindingImpl<T> createBindingFromType(Class<T> type)
+  <T> BindingImpl<T> createBindingFromType(Class<T> type, LoadStrategy loadStrategy)
       throws ResolveFailedException {
-    return createBindingFromType(type, null, SourceProviders.defaultSource());
-  }
-
-  <T> BindingImpl<T> createBindingFromType(Class<T> type, Scope scope,
-      Object source) throws ResolveFailedException {
-    BindingImpl<T> binding = createUnitializedBinding(type, scope, source);
+    BindingImpl<T> binding = createUnitializedBinding(
+        type, null, SourceProviders.defaultSource(), loadStrategy);
     initializeBinding(binding);
     return binding;
   }
@@ -474,7 +471,7 @@
    * a scope on the type if none is specified.
    */
   <T> BindingImpl<T> createUnitializedBinding(Class<T> type,
-      Scope scope, Object source) throws ResolveFailedException {
+      Scope scope, Object source, LoadStrategy loadStrategy) throws ResolveFailedException {
     // Don't try to inject arrays, or enums.
     if (type.isArray() || type.isEnum()) {
       throw new ResolveFailedException(ErrorMessages.MISSING_BINDING, type);
@@ -484,14 +481,14 @@
     ImplementedBy implementedBy = type.getAnnotation(ImplementedBy.class);
     if (implementedBy != null) {
       // TODO: Scope internal factory.
-      return createImplementedByBinding(type, implementedBy);
+      return createImplementedByBinding(type, implementedBy, loadStrategy);
     }
 
     // Handle @ProvidedBy.
     ProvidedBy providedBy = type.getAnnotation(ProvidedBy.class);
     if (providedBy != null) {
       // TODO: Scope internal factory.
-      return createProvidedByBinding(type, providedBy);
+      return createProvidedByBinding(type, providedBy, loadStrategy);
     }
 
     // We can't inject abstract classes.
@@ -512,12 +509,12 @@
 
     Key<T> key = Key.get(type);
 
-    LateBoundConstructor<T> lateBoundConstructor
-        = new LateBoundConstructor<T>();
+    LateBoundConstructor<T> lateBoundConstructor = new LateBoundConstructor<T>();
     InternalFactory<? extends T> scopedFactory
         = Scopes.scope(key, this, lateBoundConstructor, scope);
 
-    return new ClassBindingImpl<T>(this, key, source, scopedFactory, scope, lateBoundConstructor);
+    return new ClassBindingImpl<T>(this, key, source, scopedFactory, scope, lateBoundConstructor,
+        loadStrategy);
   }
 
   static class LateBoundConstructor<T> implements InternalFactory<T> {
@@ -547,7 +544,7 @@
    * Creates a binding for a type annotated with @ProvidedBy.
    */
   <T> BindingImpl<T> createProvidedByBinding(final Class<T> type,
-      ProvidedBy providedBy) throws ResolveFailedException {
+      ProvidedBy providedBy, LoadStrategy loadStrategy) throws ResolveFailedException {
     final Class<? extends Provider<?>> providerType = providedBy.value();
 
     // Make sure it's not the same type. TODO: Can we check for deeper loops?
@@ -583,14 +580,14 @@
 
     return new LinkedProviderBindingImpl<T>(this, Key.get(type),
         StackTraceElements.forType(type), internalFactory, Scopes.NO_SCOPE,
-        providerKey);
+        providerKey, loadStrategy);
   }
 
   /**
    * Creates a binding for a type annotated with @ImplementedBy.
    */
   <T> BindingImpl<T> createImplementedByBinding(Class<T> type,
-      ImplementedBy implementedBy) throws ResolveFailedException {
+      ImplementedBy implementedBy, LoadStrategy loadStrategy) throws ResolveFailedException {
     // TODO: Use scope annotation on type if present. Right now, we always
     // use NO_SCOPE.
 
@@ -622,7 +619,7 @@
 
     return new LinkedBindingImpl<T>(this, Key.get(type), 
         StackTraceElements.forType(type), internalFactory, Scopes.NO_SCOPE,
-        Key.get(subclass));
+        Key.get(subclass), loadStrategy);
   }
 
   <T> BindingImpl<T> createBindingJustInTime(Key<T> key) throws ResolveFailedException {
@@ -633,7 +630,7 @@
       // BindingImpl<Provider<X>>.
       @SuppressWarnings({ "UnnecessaryLocalVariable", "unchecked" })
       BindingImpl<T> binding
-          = (BindingImpl<T>) createProviderBinding((Key) key);
+          = (BindingImpl<T>) createProviderBinding((Key) key, LoadStrategy.LAZY);
       return binding;
     }
 
@@ -659,7 +656,7 @@
     // Create a binding based on the raw type.
     @SuppressWarnings("unchecked")
     Class<T> clazz = (Class<T>) key.getTypeLiteral().getRawType();
-    return createBindingFromType(clazz);
+    return createBindingFromType(clazz, LoadStrategy.LAZY);
   }
 
   <T> InternalFactory<? extends T> getInternalFactory(Key<T> key)
@@ -917,9 +914,6 @@
       catch (IllegalAccessException e) {
         throw new AssertionError(e);
       }
-      catch (ProvisionException e) {
-        throw e;
-      }
       catch (InvocationTargetException e) {
         Throwable cause = e.getCause() != null ? e.getCause() : e;
         throw new ProvisionException(cause,
diff --git a/src/com/google/inject/InstanceBindingImpl.java b/src/com/google/inject/InstanceBindingImpl.java
index f6ab05f..c4ac1a0 100644
--- a/src/com/google/inject/InstanceBindingImpl.java
+++ b/src/com/google/inject/InstanceBindingImpl.java
@@ -33,13 +33,12 @@
 
   InstanceBindingImpl(InjectorImpl injector, Key<T> key, Object source,
       InternalFactory<? extends T> internalFactory, T instance) {
-    super(injector, key, source, internalFactory, Scopes.NO_SCOPE);
+    super(injector, key, source, internalFactory, Scopes.NO_SCOPE, LoadStrategy.EAGER);
     this.instance = instance;
     this.provider = Providers.of(instance);
   }
 
-  @Override
-  public Provider<T> getProvider() {
+  @Override public Provider<T> getProvider() {
     return this.provider;
   }
 
@@ -55,8 +54,7 @@
     return injector.getFieldAndMethodDependenciesFor(instance.getClass());
   }
 
-  @Override
-  public String toString() {
+  @Override public String toString() {
     return new ToStringBuilder(InstanceBinding.class)
         .add("key", key)
         .add("instance", instance)
diff --git a/src/com/google/inject/InvalidBindingImpl.java b/src/com/google/inject/InvalidBindingImpl.java
index f2213b1..4a2705f 100644
--- a/src/com/google/inject/InvalidBindingImpl.java
+++ b/src/com/google/inject/InvalidBindingImpl.java
@@ -25,7 +25,7 @@
       public T get(InternalContext context, InjectionPoint<?> injectionPoint) {
         throw new AssertionError();
       }
-    }, Scopes.NO_SCOPE);
+    }, Scopes.NO_SCOPE, LoadStrategy.LAZY);
   }
 
   public void accept(BindingVisitor<? super T> bindingVisitor) {
diff --git a/src/com/google/inject/LinkedBindingImpl.java b/src/com/google/inject/LinkedBindingImpl.java
index 3693fd9..5b920f0 100644
--- a/src/com/google/inject/LinkedBindingImpl.java
+++ b/src/com/google/inject/LinkedBindingImpl.java
@@ -31,8 +31,9 @@
 
   LinkedBindingImpl(InjectorImpl injector, Key<T> key, Object source,
       InternalFactory<? extends T> internalFactory, Scope scope,
-      Key<? extends T> targetKey) {
-    super(injector, key, source, internalFactory, scope);
+      Key<? extends T> targetKey,
+      LoadStrategy loadStrategy) {
+    super(injector, key, source, internalFactory, scope, loadStrategy);
     this.targetKey = targetKey;
   }
 
diff --git a/src/com/google/inject/LinkedProviderBindingImpl.java b/src/com/google/inject/LinkedProviderBindingImpl.java
index 15f6a71..35263cc 100644
--- a/src/com/google/inject/LinkedProviderBindingImpl.java
+++ b/src/com/google/inject/LinkedProviderBindingImpl.java
@@ -31,8 +31,9 @@
 
   LinkedProviderBindingImpl(InjectorImpl injector, Key<T> key, Object source,
       InternalFactory<? extends T> internalFactory, Scope scope,
-      Key<? extends Provider<? extends T>> providerKey) {
-    super(injector, key, source, internalFactory, scope);
+      Key<? extends Provider<? extends T>> providerKey,
+      LoadStrategy loadStrategy) {
+    super(injector, key, source, internalFactory, scope, loadStrategy);
     this.providerKey = providerKey;
   }
 
diff --git a/src/com/google/inject/LoadStrategy.java b/src/com/google/inject/LoadStrategy.java
new file mode 100644
index 0000000..326e69c
--- /dev/null
+++ b/src/com/google/inject/LoadStrategy.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.google.inject;
+
+/**
+ * @author jessewilson@google.com (Jesse Wilson)
+ */
+enum LoadStrategy {
+  EAGER, LAZY
+}
diff --git a/src/com/google/inject/ProviderInstanceBindingImpl.java b/src/com/google/inject/ProviderInstanceBindingImpl.java
index 81263b1..d65253d 100644
--- a/src/com/google/inject/ProviderInstanceBindingImpl.java
+++ b/src/com/google/inject/ProviderInstanceBindingImpl.java
@@ -34,8 +34,9 @@
   ProviderInstanceBindingImpl(InjectorImpl injector, Key<T> key,
       Object source,
       InternalFactory<? extends T> internalFactory, Scope scope,
-      Provider<? extends T> providerInstance) {
-    super(injector, key, source, internalFactory, scope);
+      Provider<? extends T> providerInstance,
+      LoadStrategy loadStrategy) {
+    super(injector, key, source, internalFactory, scope, loadStrategy);
     this.providerInstance = providerInstance;
   }
 
diff --git a/src/com/google/inject/internal/ErrorMessages.java b/src/com/google/inject/internal/ErrorMessages.java
index 213f341..3bb807e 100644
--- a/src/com/google/inject/internal/ErrorMessages.java
+++ b/src/com/google/inject/internal/ErrorMessages.java
@@ -223,9 +223,6 @@
   public static final String BINDING_ALREADY_SET = "A binding to %s was already"
       + " configured at %s.";
 
-  public static final String PRELOAD_NOT_ALLOWED = "Preloading is only supported for"
-      + " singleton-scoped bindings.";
-
   public static final String ERROR_INJECTING_FIELD = "Error injecting field";
 
   public static final String ERROR_INJECTING_METHOD = "Error injecting method";