Axing SourceProviders and SourceProvider in favour of Binder.withSource and Binder.skipSources

git-svn-id: https://google-guice.googlecode.com/svn/trunk@526 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
index 7be7f28..3fac36f 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
@@ -26,7 +26,6 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.multibindings.Multibinder.RealMultibinder;
-import com.google.inject.spi.SourceProvider;
 import com.google.inject.util.Types;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
@@ -94,9 +93,6 @@
 public abstract class MapBinder<K, V> {
   private MapBinder() {}
 
-  private static final SourceProvider sourceProvider
-      = new SourceProvider(MapBinder.class, RealMapBinder.class);
-
   /**
    * Returns a new mapbinder that collects entries of {@code keyType}/{@code 
    * valueType} in a {@link Map} that is itself bound with no binding 
@@ -104,6 +100,7 @@
    */
   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, 
       Type keyType, Type valueType) {
+    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
     return newMapBinder(binder, valueType,
         Key.get(MapBinder.<K, V>mapOf(keyType, valueType)),
         Key.get(MapBinder.<K, V>mapOfProviderOf(keyType, valueType)), 
@@ -117,6 +114,7 @@
    */
   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, 
       Type keyType, Type valueType, Annotation annotation) {
+    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
     return newMapBinder(binder, valueType,
         Key.get(MapBinder.<K, V>mapOf(keyType, valueType), annotation),
         Key.get(MapBinder.<K, V>mapOfProviderOf(keyType, valueType), annotation), 
@@ -130,6 +128,7 @@
    */
   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, 
       Type keyType, Type valueType, Class<? extends Annotation> annotationType) {
+    binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
     return newMapBinder(binder, valueType,
         Key.get(MapBinder.<K, V>mapOf(keyType, valueType), annotationType),
         Key.get(MapBinder.<K, V>mapOfProviderOf(keyType, valueType), annotationType), 
@@ -156,9 +155,9 @@
   private static <K, V> MapBinder<K, V> newMapBinder(Binder binder,
       Type valueType, Key<Map<K, V>> mapKey, Key<Map<K, Provider<V>>> providerMapKey,
       Multibinder<Entry<K, Provider<V>>> entrySetBinder) {
-    RealMapBinder<K, V> mapBinder = new RealMapBinder<K, V>(binder, 
+    RealMapBinder<K, V> mapBinder = new RealMapBinder<K, V>(binder,
         valueType, mapKey, providerMapKey, entrySetBinder);
-    binder.withSource(sourceProvider.get()).install(mapBinder);
+    binder.install(mapBinder);
     return mapBinder;
   }
 
@@ -225,13 +224,12 @@
     @Override public LinkedBindingBuilder<V> addBinding(K key) {
       checkNotNull(key, "key");
       checkState(!isInitialized(), "MapBinder was already initialized");
-      Object source = sourceProvider.get();
 
       @SuppressWarnings("unchecked")
       Key<V> valueKey = (Key<V>) Key.get(valueType, new RealElement(entrySetBinder.getSetName()));
       entrySetBinder.addBinding().toInstance(new MapEntry<K, Provider<V>>(key,
-          binder.withSource(source).getProvider(valueKey)));
-      return binder.withSource(source).bind(valueKey);
+          binder.getProvider(valueKey)));
+      return binder.bind(valueKey);
     }
 
     public void configure(Binder binder) {
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
index 9068246..6f480d5 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
@@ -27,7 +27,6 @@
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
 import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.spi.SourceProvider;
 import com.google.inject.util.Types;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
@@ -85,17 +84,15 @@
 public abstract class Multibinder<T> {
   private Multibinder() {}
 
-  private static final SourceProvider sourceProvider
-      = new SourceProvider(RealMultibinder.class, Multibinder.class);
-
   /**
    * Returns a new multibinder that collects instances of {@code type} in a
    * {@link Set} that is itself bound with no binding annotation.
    */
   public static <T> Multibinder<T> newSetBinder(Binder binder, Type type) {
+    binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
     RealMultibinder<T> result = new RealMultibinder<T>(binder, type, "",
         Key.get(Multibinder.<T>setOf(type)));
-    binder.withSource(sourceProvider.get()).install(result);
+    binder.install(result);
     return result;
   }
 
@@ -104,9 +101,10 @@
    * {@link Set} that is itself bound with {@code annotation}.
    */
   public static <T> Multibinder<T> newSetBinder(Binder binder, Type type, Annotation annotation) {
+    binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
     RealMultibinder<T> result = new RealMultibinder<T>(binder, type, annotation.toString(),
         Key.get(Multibinder.<T>setOf(type), annotation));
-    binder.withSource(sourceProvider.get()).install(result);
+    binder.install(result);
     return result;
   }
 
@@ -116,9 +114,10 @@
    */
   public static <T> Multibinder<T> newSetBinder(Binder binder, Type type,
       Class<? extends Annotation> annotationType) {
+    binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
     RealMultibinder<T> result = new RealMultibinder<T>(binder, type, "@" + annotationType.getName(),
         Key.get(Multibinder.<T>setOf(type), annotationType));
-    binder.withSource(sourceProvider.get()).install(result);
+    binder.install(result);
     return result;
   }
 
@@ -193,8 +192,7 @@
     @Override public LinkedBindingBuilder<T> addBinding() {
       checkState(!isInitialized(), "Multibinder was already initialized");
 
-      return binder.withSource(sourceProvider.get())
-          .bind((Key<T>) Key.get(elementType, new RealElement(setName)));
+      return binder.bind((Key<T>) Key.get(elementType, new RealElement(setName)));
     }
 
     /**
diff --git a/spring/src/com/google/inject/spring/SpringIntegration.java b/spring/src/com/google/inject/spring/SpringIntegration.java
index 2151c60..1ac89bb 100644
--- a/spring/src/com/google/inject/spring/SpringIntegration.java
+++ b/spring/src/com/google/inject/spring/SpringIntegration.java
@@ -21,7 +21,6 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.name.Names;
-import com.google.inject.spi.SourceProvider;
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.ListableBeanFactory;
 
@@ -33,10 +32,6 @@
 public class SpringIntegration {
   private SpringIntegration() {}
 
-
-  private static final SourceProvider sourceProvider
-      = new SourceProvider(SpringIntegration.class);
-
   /**
    * Creates a provider which looks up objects from Spring using the given name.
    * Expects a binding to {@link
@@ -60,7 +55,7 @@
    * @see com.google.inject.name.Names#named(String) 
    */
   public static void bindAll(Binder binder, ListableBeanFactory beanFactory) {
-    binder = binder.withSource(sourceProvider.get());
+    binder = binder.skipSources(SpringIntegration.class);
 
     for (String name : beanFactory.getBeanDefinitionNames()) {
       Class<?> type = beanFactory.getType(name);
diff --git a/src/com/google/inject/Binder.java b/src/com/google/inject/Binder.java
index 579e12a..e35a732 100644
--- a/src/com/google/inject/Binder.java
+++ b/src/com/google/inject/Binder.java
@@ -292,7 +292,7 @@
 
   /**
    * Returns a binder that uses {@code source} as the reference location for
-   * errors in its configuration. This is typically a {@link StackTraceElement}
+   * configuration errors. This is typically a {@link StackTraceElement}
    * for {@code .java} source but it could any binding source, such as the
    * path to a {@code .properties} file.
    *
@@ -301,4 +301,15 @@
    * @return a binder that shares its configuration with this binder
    */
   Binder withSource(Object source);
+
+  /**
+   * Returns a binder that skips {@code classesToSkip} when identify the
+   * calling code. The caller's {@link StackTraceElement} is used to locate
+   * the source of configuration errors.
+   *
+   * @param classesToSkip library classes that create bindings on behalf of
+   *      their clients.
+   * @return a binder that shares its configuration with this binder.
+   */
+  Binder skipSources(Class... classesToSkip);
 }
diff --git a/src/com/google/inject/ConvertToTypesCommandProcessor.java b/src/com/google/inject/ConvertToTypesCommandProcessor.java
index d5f5172..93b8609 100644
--- a/src/com/google/inject/ConvertToTypesCommandProcessor.java
+++ b/src/com/google/inject/ConvertToTypesCommandProcessor.java
@@ -20,11 +20,11 @@
 import com.google.inject.commands.ConvertToTypesCommand;
 import com.google.inject.internal.Errors;
 import com.google.inject.internal.MatcherAndConverter;
+import com.google.inject.internal.SourceProvider;
 import com.google.inject.internal.Strings;
 import com.google.inject.matcher.AbstractMatcher;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.matcher.Matchers;
-import com.google.inject.spi.SourceProvider;
 import com.google.inject.spi.TypeConverter;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
diff --git a/src/com/google/inject/InjectorBuilder.java b/src/com/google/inject/InjectorBuilder.java
index 74be70f..b026a89 100644
--- a/src/com/google/inject/InjectorBuilder.java
+++ b/src/com/google/inject/InjectorBuilder.java
@@ -26,9 +26,9 @@
 import com.google.inject.commands.FutureInjector;
 import com.google.inject.internal.Errors;
 import com.google.inject.internal.ErrorsException;
+import com.google.inject.internal.SourceProvider;
 import com.google.inject.internal.Stopwatch;
 import com.google.inject.spi.InjectionPoint;
-import com.google.inject.spi.SourceProvider;
 import java.lang.reflect.Member;
 import java.util.List;
 import java.util.logging.Logger;
diff --git a/src/com/google/inject/InjectorImpl.java b/src/com/google/inject/InjectorImpl.java
index 6f6eb1e..55d47ea 100644
--- a/src/com/google/inject/InjectorImpl.java
+++ b/src/com/google/inject/InjectorImpl.java
@@ -31,13 +31,13 @@
 import com.google.inject.internal.MatcherAndConverter;
 import com.google.inject.internal.Nullability;
 import com.google.inject.internal.ReferenceCache;
+import com.google.inject.internal.SourceProvider;
 import com.google.inject.internal.StackTraceElements;
 import com.google.inject.internal.ToStringBuilder;
 import com.google.inject.spi.BindingVisitor;
 import com.google.inject.spi.ConvertedConstantBinding;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.ProviderBinding;
-import com.google.inject.spi.SourceProvider;
 import com.google.inject.util.Providers;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
diff --git a/src/com/google/inject/InternalFactoryToProviderAdapter.java b/src/com/google/inject/InternalFactoryToProviderAdapter.java
index b1424f8..c13a454 100644
--- a/src/com/google/inject/InternalFactoryToProviderAdapter.java
+++ b/src/com/google/inject/InternalFactoryToProviderAdapter.java
@@ -19,8 +19,8 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.inject.internal.Errors;
 import com.google.inject.internal.ErrorsException;
+import com.google.inject.internal.SourceProvider;
 import com.google.inject.spi.InjectionPoint;
-import com.google.inject.spi.SourceProvider;
 
 /**
  * @author crazybob@google.com (Bob Lee)
diff --git a/src/com/google/inject/commands/BindCommand.java b/src/com/google/inject/commands/BindCommand.java
index 996841b..46d169a 100644
--- a/src/com/google/inject/commands/BindCommand.java
+++ b/src/com/google/inject/commands/BindCommand.java
@@ -26,7 +26,6 @@
 import com.google.inject.binder.ConstantBindingBuilder;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.binder.ScopedBindingBuilder;
-import com.google.inject.spi.SourceProvider;
 import java.lang.annotation.Annotation;
 
 /**
@@ -36,9 +35,6 @@
  */
 public final class BindCommand<T> implements Command {
 
-  private static final SourceProvider sourceProvider = new SourceProvider(
-      BindCommand.BindingBuilder.class);
-
   private static final BindTarget<Object> EMPTY_BIND_TARGET = new AbstractTarget<Object>() {
     public ScopedBindingBuilder execute(LinkedBindingBuilder<Object> linkedBindingBuilder) {
       return linkedBindingBuilder;
@@ -136,7 +132,7 @@
     private final Binder binder;
 
     BindingBuilder(Binder binder) {
-      this.binder = binder;
+      this.binder = binder.skipSources(BindingBuilder.class);
     }
 
     public LinkedBindingBuilder<T> annotatedWith(
@@ -316,25 +312,25 @@
 
     private void checkNotTargetted() {
       if (bindTarget != EMPTY_BIND_TARGET) {
-        binder.withSource(sourceProvider.get()).addError(IMPLEMENTATION_ALREADY_SET);
+        binder.addError(IMPLEMENTATION_ALREADY_SET);
       }
     }
 
     private void checkNotAnnotated() {
       if (BindCommand.this.key.getAnnotationType() != null) {
-        binder.withSource(sourceProvider.get()).addError(ANNOTATION_ALREADY_SPECIFIED);
+        binder.addError(ANNOTATION_ALREADY_SPECIFIED);
       }
     }
 
     private void checkNotScoped() {
       // Scoping isn't allowed when we have only one instance.
       if (bindTarget.get() != null) {
-        binder.withSource(sourceProvider.get()).addError(SINGLE_INSTANCE_AND_SCOPE);
+        binder.addError(SINGLE_INSTANCE_AND_SCOPE);
         return;
       }
 
       if (bindScoping != EMPTY_SCOPING) {
-        binder.withSource(sourceProvider.get()).addError(SCOPE_ALREADY_SET);
+        binder.addError(SCOPE_ALREADY_SET);
       }
     }
 
diff --git a/src/com/google/inject/commands/BindConstantCommand.java b/src/com/google/inject/commands/BindConstantCommand.java
index d51e349..a340cc8 100644
--- a/src/com/google/inject/commands/BindConstantCommand.java
+++ b/src/com/google/inject/commands/BindConstantCommand.java
@@ -17,7 +17,6 @@
 package com.google.inject.commands;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Key;
 import com.google.inject.Provider;
@@ -25,7 +24,6 @@
 import com.google.inject.binder.ConstantBindingBuilder;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.binder.ScopedBindingBuilder;
-import com.google.inject.spi.SourceProvider;
 import java.lang.annotation.Annotation;
 
 /**
@@ -34,9 +32,6 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public final class BindConstantCommand implements Command {
-  private static final SourceProvider sourceProvider = new SourceProvider(
-      BindingBuilder.class, AbstractModule.class);
-
   private final Object source;
   private BindingAnnotation bindingAnnotation;
   private ConstantTarget<?> target;
@@ -112,7 +107,7 @@
     private final Binder binder;
 
     BindingBuilder(Binder binder) {
-      this.binder = binder;
+      this.binder = binder.skipSources(BindingBuilder.class);
     }
 
     public ConstantBindingBuilder annotatedWith(final Class<? extends Annotation> annotationType) {
@@ -347,13 +342,13 @@
 
     private void assertNoBindingAnnotation() {
       if (bindingAnnotation != null) {
-        binder.withSource(sourceProvider.get()).addError(ANNOTATION_ALREADY_SPECIFIED);
+        binder.addError(ANNOTATION_ALREADY_SPECIFIED);
       }
     }
 
     private void assertNoTarget() {
       if (target != null) {
-        binder.withSource(sourceProvider.get()).addError(CONSTANT_VALUE_ALREADY_SET);
+        binder.addError(CONSTANT_VALUE_ALREADY_SET);
       }
     }
 
diff --git a/src/com/google/inject/commands/CommandRecorder.java b/src/com/google/inject/commands/CommandRecorder.java
index d91b01a..f3bb7a2 100644
--- a/src/com/google/inject/commands/CommandRecorder.java
+++ b/src/com/google/inject/commands/CommandRecorder.java
@@ -16,7 +16,7 @@
 
 package com.google.inject.commands;
 
-import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import com.google.inject.AbstractModule;
@@ -29,9 +29,9 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.binder.AnnotatedBindingBuilder;
 import com.google.inject.binder.AnnotatedConstantBindingBuilder;
+import com.google.inject.internal.SourceProvider;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.spi.Message;
-import com.google.inject.spi.SourceProvider;
 import com.google.inject.spi.TypeConverter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
@@ -48,9 +48,6 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public final class CommandRecorder {
-  private static final SourceProvider sourceProvider = new SourceProvider(
-      RecordingBinder.class, AbstractModule.class);
-
   private Stage currentStage = Stage.DEVELOPMENT;
   private final EarlyRequestsProvider earlyRequestsProvider;
 
@@ -91,19 +88,28 @@
   private class RecordingBinder implements Binder {
     private final Set<Module> modules;
     private final List<Command> commands;
+    private final Object source;
+    private final SourceProvider sourceProvider;
 
     private RecordingBinder() {
       modules = Sets.newHashSet();
       commands = Lists.newArrayList();
+      source = null;
+      sourceProvider
+          = new SourceProvider().plusSkippedClasses(RecordingBinder.class, AbstractModule.class);
     }
 
     /**
      * Creates a recording binder that's backed by the same configuration as
      * {@code backingBinder}.
      */
-    private RecordingBinder(RecordingBinder backingBinder) {
-      modules = backingBinder.modules;
-      commands = backingBinder.commands;
+    private RecordingBinder(RecordingBinder parent, Object source, SourceProvider sourceProvider) {
+      checkArgument(source == null ^ sourceProvider == null);
+
+      modules = parent.modules;
+      commands = parent.commands;
+      this.source = source;
+      this.sourceProvider = sourceProvider;
     }
 
     public void bindInterceptor(
@@ -186,17 +192,23 @@
     }
 
     public Binder withSource(final Object source) {
-      checkNotNull(source, "source");
+      return new RecordingBinder(this, source, null);
+    }
 
-      return new RecordingBinder(this) {
-        @Override protected Object getSource() {
-          return source;
-        }
-      };
+    public Binder skipSources(Class... classesToSkip) {
+      // if a source is specified explicitly, we don't need to skip sources
+      if (source != null) {
+        return this;
+      }
+
+      SourceProvider newSourceProvider = sourceProvider.plusSkippedClasses(classesToSkip);
+      return new RecordingBinder(this, null, newSourceProvider);
     }
 
     protected Object getSource() {
-      return sourceProvider.get();
+      return sourceProvider != null
+          ? sourceProvider.get()
+          : source;
     }
 
     @Override public String toString() {
diff --git a/src/com/google/inject/internal/Errors.java b/src/com/google/inject/internal/Errors.java
index 0ee4702..4da99f5 100644
--- a/src/com/google/inject/internal/Errors.java
+++ b/src/com/google/inject/internal/Errors.java
@@ -28,7 +28,6 @@
 import com.google.inject.TypeLiteral;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.Message;
-import com.google.inject.spi.SourceProvider;
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
diff --git a/src/com/google/inject/internal/SourceProvider.java b/src/com/google/inject/internal/SourceProvider.java
new file mode 100644
index 0000000..1f99ee8
--- /dev/null
+++ b/src/com/google/inject/internal/SourceProvider.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2006 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.internal;
+
+import com.google.common.collect.ImmutableSet;
+import static com.google.common.collect.Iterables.concat;
+import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Provides access to the calling line of code.
+ * 
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class SourceProvider {
+
+  /** Indicates that the source is unknown. */
+  public static final Object UNKNOWN_SOURCE = "[unknown source]";
+
+  private final ImmutableSet<String> classNamesToSkip;
+
+  public SourceProvider() {
+    this.classNamesToSkip = ImmutableSet.of(SourceProvider.class.getName());
+  }
+
+  public static final SourceProvider DEFAULT_INSTANCE
+      = new SourceProvider(ImmutableSet.of(SourceProvider.class.getName()));
+
+  private SourceProvider(Iterable<String> classesToSkip) {
+    this.classNamesToSkip = ImmutableSet.copyOf(classesToSkip);
+  }
+
+  /** Returns a new instance that also skips {@code moreClassesToSkip}. */
+  public SourceProvider plusSkippedClasses(Class... moreClassesToSkip) {
+    return new SourceProvider(concat(classNamesToSkip, asStrings(moreClassesToSkip)));
+  }
+
+  /** Returns the class names as Strings */
+  private static List<String> asStrings(Class... classes) {
+    List<String> strings = Lists.newArrayList();
+    for (Class c : classes) {
+      strings.add(c.getName());
+    }
+    return strings;
+  }
+
+  /** Returns an immutable set with the names of the classes that are skipped. */
+  public Set<String> getSkippedClassNames() {
+    return classNamesToSkip;
+  }
+
+  /**
+   * Returns the calling line of code. The selected line is the nearest to the top of the stack that
+   * is not skipped.
+   */
+  public StackTraceElement get() {
+    for (final StackTraceElement element : new Throwable().getStackTrace()) {
+      String className = element.getClassName();
+      if (!classNamesToSkip.contains(className)) {
+        return element;
+      }
+    }
+    throw new AssertionError();
+  }
+}
diff --git a/src/com/google/inject/internal/StackTraceElements.java b/src/com/google/inject/internal/StackTraceElements.java
index fcabe40..99c7952 100644
--- a/src/com/google/inject/internal/StackTraceElements.java
+++ b/src/com/google/inject/internal/StackTraceElements.java
@@ -18,7 +18,6 @@
 
 import static com.google.inject.internal.ReferenceType.SOFT;
 import static com.google.inject.internal.ReferenceType.WEAK;
-import com.google.inject.spi.SourceProvider;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Member;
diff --git a/src/com/google/inject/name/Names.java b/src/com/google/inject/name/Names.java
index 53bc7d5..146a2ab 100644
--- a/src/com/google/inject/name/Names.java
+++ b/src/com/google/inject/name/Names.java
@@ -16,10 +16,8 @@
 
 package com.google.inject.name;
 
-import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Key;
-import com.google.inject.spi.SourceProvider;
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.Properties;
@@ -31,9 +29,6 @@
  */
 public class Names {
 
-  private static final SourceProvider sourceProvider = new SourceProvider(
-      Names.class, AbstractModule.class);
-
   private Names() {}
 
   /**
@@ -48,7 +43,7 @@
    * {@code properties}.
    */
   public static void bindProperties(Binder binder, Map<String, String> properties) {
-    binder = binder.withSource(sourceProvider.get());
+    binder = binder.skipSources(Names.class);
     for (Map.Entry<String, String> entry : properties.entrySet()) {
       String key = entry.getKey();
       String value = entry.getValue();
@@ -62,7 +57,7 @@
    * {@link Properties#defaults defaults}.
    */
   public static void bindProperties(Binder binder, Properties properties) {
-    binder = binder.withSource(sourceProvider.get());
+    binder = binder.skipSources(Names.class);
 
     // use enumeration to include the default properties
     for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements(); ) {
diff --git a/src/com/google/inject/spi/Dependency.java b/src/com/google/inject/spi/Dependency.java
deleted file mode 100644
index 46fc84a..0000000
--- a/src/com/google/inject/spi/Dependency.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007 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.spi;
-
-import com.google.inject.Key;
-import java.lang.reflect.Member;
-
-/**
- * Represents a single dependency. Composed of where the dependency comes from
- * and how it's fulfilled. Each injectable field has a corresponding Dependency.
- * Each parameter in an injectable method or constructor has its own Dependency
- * instance.
- *
- * @author crazybob@google.com (Bob Lee)
- */
-public interface Dependency<T> {
-
-  /**
-   * Gets the key used to resolve this dependency. Equivalent to
-   * {@code getBinding().getKey()}.
-   */
-  Key<T> getKey();
-
-  /**
-   * Gets the member (constructor, method, or field) which has the dependency.
-   */
-  Member getMember();
-
-  /**
-   * If the member is a constructor or method, you'll have one Dependency per
-   * parameter, and this method returns the index of the parameter represented
-   * by this Dependency. If the member is a field, this method returns
-   * {@code -1}.
-   */
-  int getParameterIndex();
-
-  /**
-   * Returns true if the member accepts nulls, false otherwise.
-   */
-  boolean allowsNull();
-}
diff --git a/src/com/google/inject/spi/Message.java b/src/com/google/inject/spi/Message.java
index 5b5a53c..f83ec65 100644
--- a/src/com/google/inject/spi/Message.java
+++ b/src/com/google/inject/spi/Message.java
@@ -19,6 +19,7 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.internal.Errors;
+import com.google.inject.internal.SourceProvider;
 import java.io.Serializable;
 import java.util.List;
 
diff --git a/test/com/google/inject/AllTests.java b/test/com/google/inject/AllTests.java
index 681f1db..dfc78e8 100644
--- a/test/com/google/inject/AllTests.java
+++ b/test/com/google/inject/AllTests.java
@@ -19,7 +19,12 @@
 import com.google.inject.commands.CommandRecorderTest;
 import com.google.inject.commands.CommandReplayerTest;
 import com.google.inject.commands.CommandRewriteTest;
-import com.google.inject.internal.*;
+import com.google.inject.internal.FinalizableReferenceQueueTest;
+import com.google.inject.internal.LineNumbersTest;
+import com.google.inject.internal.ReferenceCacheTest;
+import com.google.inject.internal.ReferenceMapTest;
+import com.google.inject.internal.ReferenceMapTestSuite;
+import com.google.inject.internal.UniqueAnnotationsTest;
 import com.google.inject.matcher.MatcherTest;
 import com.google.inject.util.ProvidersTest;
 import com.google.inject.util.TypesTest;