Changed the InjectionPoint factory methods. Now the ConfigurationException includes a partial value, which means that a sink collection doesn't need to be passed in.

git-svn-id: https://google-guice.googlecode.com/svn/trunk@670 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/ConfigurationException.java b/src/com/google/inject/ConfigurationException.java
index b67a20c..e74a35b 100644
--- a/src/com/google/inject/ConfigurationException.java
+++ b/src/com/google/inject/ConfigurationException.java
@@ -16,6 +16,7 @@
 
 package com.google.inject;
 
+import static com.google.common.base.Preconditions.checkState;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.internal.Errors;
 import com.google.inject.spi.Message;
@@ -30,6 +31,7 @@
 public final class ConfigurationException extends RuntimeException {
 
   private final ImmutableSet<Message> messages;
+  private Object partialValue = null;
 
   /** Creates a ConfigurationException containing {@code messages}. */
   public ConfigurationException(Iterable<Message> messages) {
@@ -37,11 +39,32 @@
     initCause(Errors.getOnlyCause(this.messages));
   }
 
+  /** Returns a copy of this configuration exception with the specified partial value. */
+  public ConfigurationException withPartialValue(Object partialValue) {
+    checkState(this.partialValue == null,
+        "Can't clobber existing partial value %s with %s", this.partialValue, partialValue);
+    ConfigurationException result = new ConfigurationException(messages);
+    result.partialValue = partialValue;
+    return result;
+  }
+
   /** Returns messages for the errors that caused this exception. */
   public Collection<Message> getErrorMessages() {
     return messages;
   }
 
+  /**
+   * Returns a value that was only partially computed due to this exception. The caller can use
+   * this while collecting additional configuration problems.
+   *
+   * @return the partial value, or {@code null} if none was set. The type of the partial value is
+   *      specified by the throwing method.
+   */
+  @SuppressWarnings("unchecked") // this is *extremely* unsafe. We trust the caller here.
+  public <E> E getPartialValue() {
+    return (E) partialValue;
+  }
+
   @Override public String getMessage() {
     return Errors.format("Guice configuration errors", messages);
   }
diff --git a/src/com/google/inject/ConstructorInjector.java b/src/com/google/inject/ConstructorInjector.java
index e9a5138..1699835 100644
--- a/src/com/google/inject/ConstructorInjector.java
+++ b/src/com/google/inject/ConstructorInjector.java
@@ -42,7 +42,7 @@
     this.implementation = implementation;
 
     try {
-      this.injectionPoint = InjectionPoint.forConstructorOf(implementation.getType());
+      this.injectionPoint = InjectionPoint.forConstructorOf(implementation);
     } catch (ConfigurationException e) {
       throw errors.merge(e.getErrorMessages()).toException();
     }
diff --git a/src/com/google/inject/InjectionRequestProcessor.java b/src/com/google/inject/InjectionRequestProcessor.java
index 39858cb..b761b33 100644
--- a/src/com/google/inject/InjectionRequestProcessor.java
+++ b/src/com/google/inject/InjectionRequestProcessor.java
@@ -17,7 +17,6 @@
 package com.google.inject;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.inject.internal.Errors;
 import com.google.inject.internal.ErrorsException;
@@ -25,6 +24,7 @@
 import com.google.inject.spi.InjectionRequest;
 import com.google.inject.spi.StaticInjectionRequest;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Handles {@link Binder#requestInjection} and {@link Binder#requestStaticInjection} commands.
@@ -50,16 +50,16 @@
   }
 
   @Override public Boolean visitInjectionRequest(InjectionRequest command) {
-    List<InjectionPoint> injectionPointsList = Lists.newArrayList();
+    Set<InjectionPoint> injectionPoints;
     try {
-      InjectionPoint.addForInstanceMethodsAndFields(
-          command.getInstance().getClass(), injectionPointsList);
+      injectionPoints = InjectionPoint.forInstanceMethodsAndFields(
+          command.getInstance().getClass());
     } catch (ConfigurationException e) {
       errors.merge(e.getErrorMessages());
+      injectionPoints = e.getPartialValue();
     }
 
-    memberInjector.requestInjection(command.getInstance(), command.getSource(),
-        ImmutableSet.copyOf(injectionPointsList));
+    memberInjector.requestInjection(command.getInstance(), command.getSource(), injectionPoints);
     return true;
   }
 
@@ -88,11 +88,12 @@
 
     void validate(final InjectorImpl injector) {
       Errors errorsForMember = errors.withSource(source);
-      List<InjectionPoint> injectionPoints = Lists.newArrayList();
+      Set<InjectionPoint> injectionPoints;
       try {
-        InjectionPoint.addForStaticMethodsAndFields(type, injectionPoints);
+        injectionPoints = InjectionPoint.forStaticMethodsAndFields(type);
       } catch (ConfigurationException e) {
         errors.merge(e.getErrorMessages());
+        injectionPoints = e.getPartialValue();
       }
       memberInjectors = injector.getInjectors(injectionPoints, errorsForMember);
     }
diff --git a/src/com/google/inject/InjectorImpl.java b/src/com/google/inject/InjectorImpl.java
index 8a785ce..8786d19 100644
--- a/src/com/google/inject/InjectorImpl.java
+++ b/src/com/google/inject/InjectorImpl.java
@@ -50,6 +50,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Default {@link Injector} implementation.
@@ -617,11 +618,12 @@
     protected ImmutableList<SingleMemberInjector> create(TypeLiteral<?> type, Errors errors)
         throws ErrorsException {
       int numErrorsBefore = errors.size();
-      List<InjectionPoint> injectionPoints = Lists.newArrayList();
+      Set<InjectionPoint> injectionPoints;
       try {
-        InjectionPoint.addForInstanceMethodsAndFields(type.getType(), injectionPoints);
+        injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type);
       } catch (ConfigurationException e) {
         errors.merge(e.getErrorMessages());
+        injectionPoints = e.getPartialValue();
       }
       ImmutableList<SingleMemberInjector> injectors = getInjectors(injectionPoints, errors);
       errors.throwIfNewErrors(numErrorsBefore);
@@ -631,7 +633,7 @@
 
   /** Returns the injectors for the specified injection points. */
   ImmutableList<SingleMemberInjector> getInjectors(
-      List<InjectionPoint> injectionPoints, Errors errors) {
+      Set<InjectionPoint> injectionPoints, Errors errors) {
     List<SingleMemberInjector> injectors = Lists.newArrayList();
     for (InjectionPoint injectionPoint : injectionPoints) {
       try {
diff --git a/src/com/google/inject/internal/ModuleBinding.java b/src/com/google/inject/internal/ModuleBinding.java
index 2b34100..d15845a 100644
--- a/src/com/google/inject/internal/ModuleBinding.java
+++ b/src/com/google/inject/internal/ModuleBinding.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
 import com.google.inject.Binder;
 import com.google.inject.Binding;
 import com.google.inject.ConfigurationException;
@@ -39,7 +38,6 @@
 import com.google.inject.spi.Message;
 import com.google.inject.util.Providers;
 import java.lang.annotation.Annotation;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -204,16 +202,15 @@
       }
 
       // lookup the injection points, adding any errors to the binder's errors list
-      List<InjectionPoint> injectionPointsList = Lists.newArrayList();
+      Set<InjectionPoint> injectionPoints;
       try {
-        InjectionPoint.addForInstanceMethodsAndFields(instance.getClass(), injectionPointsList);
+        injectionPoints = InjectionPoint.forInstanceMethodsAndFields(instance.getClass());
       } catch (ConfigurationException e) {
         for (Message message : e.getErrorMessages()) {
           binder.addError(message);
         }
+        injectionPoints = e.getPartialValue();
       }
-      ImmutableSet<InjectionPoint> injectionPoints = ImmutableSet.copyOf(injectionPointsList);
-
       target = new InstanceTarget<T>(instance, injectionPoints);
     }
 
@@ -222,19 +219,20 @@
       checkNotTargetted();
 
       // lookup the injection points, adding any errors to the binder's errors list
-      List<InjectionPoint> injectionPointsList = Lists.newArrayList();
+      Set<InjectionPoint> injectionPoints;
       try {
-        InjectionPoint.addForInstanceMethodsAndFields(provider.getClass(), injectionPointsList);
+        injectionPoints = InjectionPoint.forInstanceMethodsAndFields(provider.getClass());
       } catch (ConfigurationException e) {
         for (Message message : e.getErrorMessages()) {
           binder.addError(message);
         }
+        injectionPoints = e.getPartialValue();
       }
-      final ImmutableSet<InjectionPoint> injectionPoints = ImmutableSet.copyOf(injectionPointsList);
 
+      final Set<InjectionPoint> injectionPointsFinal = injectionPoints;
       target = new Target<T>() {
         public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
-          return visitor.visitProvider(provider, injectionPoints);
+          return visitor.visitProvider(provider, injectionPointsFinal);
         }
       };
       return this;
@@ -469,9 +467,9 @@
     private final T instance;
     private final ImmutableSet<InjectionPoint> injectionPoints;
 
-    public InstanceTarget(T instance, ImmutableSet<InjectionPoint> injectionPoints) {
+    public InstanceTarget(T instance, Set<InjectionPoint> injectionPoints) {
       this.instance = instance;
-      this.injectionPoints = injectionPoints;
+      this.injectionPoints = ImmutableSet.copyOf(injectionPoints);
     }
 
     public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) {
diff --git a/src/com/google/inject/spi/InjectionPoint.java b/src/com/google/inject/spi/InjectionPoint.java
index 1d5aac9..4f03ee6 100644
--- a/src/com/google/inject/spi/InjectionPoint.java
+++ b/src/com/google/inject/spi/InjectionPoint.java
@@ -17,6 +17,7 @@
 package com.google.inject.spi;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.inject.ConfigurationException;
 import com.google.inject.Inject;
@@ -41,6 +42,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 /**
  * A constructor, field or method that can receive injections. Typically this is a member with the
@@ -181,10 +183,9 @@
    *     constructor, or if parameters of the injectable constructor are malformed, such as a
    *     parameter with multiple binding annotations.
    */
-  public static InjectionPoint forConstructorOf(Type type) {
-    Errors errors = new Errors(type);
-    TypeLiteral<?> typeLiteral = TypeLiteral.get(type);
-    Class<?> rawType = MoreTypes.getRawType(type);
+  public static InjectionPoint forConstructorOf(TypeLiteral<?> type) {
+    Class<?> rawType = MoreTypes.getRawType(type.getType());
+    Errors errors = new Errors(rawType);
 
     Constructor<?> injectableConstructor = null;
     for (Constructor<?> constructor : rawType.getDeclaredConstructors()) {
@@ -206,7 +207,7 @@
     errors.throwConfigurationExceptionIfErrorsExist();
 
     if (injectableConstructor != null) {
-      return new InjectionPoint(typeLiteral, injectableConstructor);
+      return new InjectionPoint(type, injectableConstructor);
     }
 
     // If no annotated constructor is found, look for a no-arg constructor instead.
@@ -221,7 +222,7 @@
       }
 
       checkForMisplacedBindingAnnotations(noArgConstructor, errors);
-      return new InjectionPoint(typeLiteral, noArgConstructor);
+      return new InjectionPoint(type, noArgConstructor);
     } catch (NoSuchMethodException e) {
       errors.missingConstructor(rawType);
       throw new ConfigurationException(errors.getMessages());
@@ -229,38 +230,92 @@
   }
 
   /**
-   * Adds all static method and field injection points on {@code type} to {@code injectionPoints}.
-   * All fields are added first, and then all methods. Within the fields, supertype fields are added
-   * before subtype fields. Similarly, supertype methods are added before subtype methods.
+   * Returns a new injection point for the injectable constructor of {@code type}.
    *
-   * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. When such an exception is thrown, the valid
-   *      injection points are still added to the collection.
+   * @param type a concrete type with exactly one constructor annotated {@literal @}{@link Inject},
+   *     or a no-arguments constructor that is not private.
+   * @throws ConfigurationException if there is no injectable constructor, more than one injectable
+   *     constructor, or if parameters of the injectable constructor are malformed, such as a
+   *     parameter with multiple binding annotations.
    */
-  public static void addForStaticMethodsAndFields(Type type, Collection<InjectionPoint> sink) {
-    Errors errors = new Errors();
-    TypeLiteral<?> typeLiteral = TypeLiteral.get(type);
-    addInjectionPoints(typeLiteral, Factory.FIELDS, true, sink, errors);
-    addInjectionPoints(typeLiteral, Factory.METHODS, true, sink, errors);
-    errors.throwConfigurationExceptionIfErrorsExist();
+  public static InjectionPoint forConstructorOf(Class<?> type) {
+    return forConstructorOf(TypeLiteral.get(type));
   }
 
   /**
-   * Adds all instance method and field injection points on {@code type} to {@code injectionPoints}.
-   * All fields are added first, and then all methods. Within the fields, supertype fields are added
-   * before subtype fields. Similarly, supertype methods are added before subtype methods.
+   * Returns all static method and field injection points on {@code type}. All fields are added
+   * first, and then all methods. Within the fields, supertype fields are added before subtype
+   * fields. Similarly, supertype methods are added before subtype methods.
    *
    * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
-   *      a field with multiple binding annotations. When such an exception is thrown, the valid
-   *      injection points are still added to the collection.
+   *      a field with multiple binding annotations. The exception's {@link
+   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+   *      of the valid injection points.
    */
-  public static void addForInstanceMethodsAndFields(Type type, Collection<InjectionPoint> sink) {
-    // TODO (crazybob): Filter out overridden members.
+  public static Set<InjectionPoint> forStaticMethodsAndFields(TypeLiteral type) {
+    List<InjectionPoint> sink = Lists.newArrayList();
     Errors errors = new Errors();
-    TypeLiteral<?> typeLiteral = TypeLiteral.get(type);
-    addInjectionPoints(typeLiteral, Factory.FIELDS, false, sink, errors);
-    addInjectionPoints(typeLiteral, Factory.METHODS, false, sink, errors);
-    errors.throwConfigurationExceptionIfErrorsExist();
+
+    addInjectionPoints(type, Factory.FIELDS, true, sink, errors);
+    addInjectionPoints(type, Factory.METHODS, true, sink, errors);
+
+    ImmutableSet<InjectionPoint> result = ImmutableSet.copyOf(sink);
+    if (errors.hasErrors()) {
+      throw new ConfigurationException(errors.getMessages()).withPartialValue(result);
+    }
+    return result;
+  }
+  /**
+   * Returns all static method and field injection points on {@code type}. All fields are added
+   * first, and then all methods. Within the fields, supertype fields are added before subtype
+   * fields. Similarly, supertype methods are added before subtype methods.
+   *
+   * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+   *      a field with multiple binding annotations. The exception's {@link
+   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+   *      of the valid injection points.
+   */
+  public static Set<InjectionPoint> forStaticMethodsAndFields(Class<?> type) {
+    return forStaticMethodsAndFields(TypeLiteral.get(type));
+  }
+
+  /**
+   * Returns all instance method and field injection points on {@code type}. All fields are added
+   * first, and then all methods. Within the fields, supertype fields are added before subtype
+   * fields. Similarly, supertype methods are added before subtype methods.
+   *
+   * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+   *      a field with multiple binding annotations. The exception's {@link
+   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+   *      of the valid injection points.
+   */
+  public static Set<InjectionPoint> forInstanceMethodsAndFields(TypeLiteral<?> type) {
+    List<InjectionPoint> sink = Lists.newArrayList();
+    Errors errors = new Errors();
+
+    // TODO (crazybob): Filter out overridden members.
+    addInjectionPoints(type, Factory.FIELDS, false, sink, errors);
+    addInjectionPoints(type, Factory.METHODS, false, sink, errors);
+
+    ImmutableSet<InjectionPoint> result = ImmutableSet.copyOf(sink);
+    if (errors.hasErrors()) {
+      throw new ConfigurationException(errors.getMessages()).withPartialValue(result);
+    }
+    return result;
+  }
+
+  /**
+   * Returns all instance method and field injection points on {@code type}. All fields are added
+   * first, and then all methods. Within the fields, supertype fields are added before subtype
+   * fields. Similarly, supertype methods are added before subtype methods.
+   *
+   * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
+   *      a field with multiple binding annotations. The exception's {@link
+   *      ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>}
+   *      of the valid injection points.
+   */
+  public static Set<InjectionPoint> forInstanceMethodsAndFields(Class<?> type) {
+    return forInstanceMethodsAndFields(TypeLiteral.get(type));
   }
 
   private static void checkForMisplacedBindingAnnotations(Member member, Errors errors) {
diff --git a/test/com/google/inject/ProxyFactoryTest.java b/test/com/google/inject/ProxyFactoryTest.java
index 9d0dd2e..93ce73f 100644
--- a/test/com/google/inject/ProxyFactoryTest.java
+++ b/test/com/google/inject/ProxyFactoryTest.java
@@ -46,8 +46,8 @@
     aspects.add(new MethodAspect(any(), any(), interceptor));
     ProxyFactory factory = new ProxyFactory(aspects);
 
-    ConstructionProxy<Simple> constructionProxy
-        = factory.createConstructionProxy(InjectionPoint.forConstructorOf(Simple.class));
+    ConstructionProxy<Simple> constructionProxy = factory.createConstructionProxy(
+        InjectionPoint.forConstructorOf(Simple.class));
 
     Simple simple = constructionProxy.newInstance();
     simple.invoke();
@@ -79,10 +79,8 @@
     aspects.add(new MethodAspect(only(Bar.class), annotatedWith(Intercept.class), interceptor));
     ProxyFactory factory = new ProxyFactory(aspects);
 
-    ConstructionProxy<Foo> fooFactory =
-        factory.get(InjectionPoint.forConstructorOf(Foo.class));
-    ConstructionProxy<Bar> barFactory =
-        factory.get(InjectionPoint.forConstructorOf(Bar.class));
+    ConstructionProxy<Foo> fooFactory = factory.get(InjectionPoint.forConstructorOf(Foo.class));
+    ConstructionProxy<Bar> barFactory = factory.get(InjectionPoint.forConstructorOf(Bar.class));
 
     Foo foo = fooFactory.newInstance();
     Bar bar = barFactory.newInstance();
@@ -133,8 +131,7 @@
     aspects.add(new MethodAspect(any(), any(), interceptor));
     ProxyFactory factory = new ProxyFactory(aspects);
 
-    ConstructionProxy<A> constructor =
-        factory.get(InjectionPoint.forConstructorOf(A.class));
+    ConstructionProxy<A> constructor = factory.get(InjectionPoint.forConstructorOf(A.class));
 
     A a = constructor.newInstance(5);
     a.a();
@@ -148,8 +145,7 @@
     aspects.add(new MethodAspect(not(any()), not(any()), interceptor));
     ProxyFactory factory = new ProxyFactory(aspects);
 
-    ConstructionProxy<A> constructor =
-        factory.get(InjectionPoint.forConstructorOf(A.class));
+    ConstructionProxy<A> constructor = factory.get(InjectionPoint.forConstructorOf(A.class));
 
     A a = constructor.newInstance(5);
     assertEquals(A.class, a.getClass());
@@ -171,8 +167,8 @@
     aspects.add(new MethodAspect(any(), any(), doubleInterceptor, countingInterceptor));
     ProxyFactory factory = new ProxyFactory(aspects);
 
-    ConstructionProxy<Counter> constructor =
-        factory.get(InjectionPoint.forConstructorOf(Counter.class));
+    ConstructionProxy<Counter> constructor
+        = factory.get(InjectionPoint.forConstructorOf(Counter.class));
 
     Counter counter = constructor.newInstance();
     counter.inc();
diff --git a/test/com/google/inject/spi/InjectionPointTest.java b/test/com/google/inject/spi/InjectionPointTest.java
index 9760f0e..39d823d 100644
--- a/test/com/google/inject/spi/InjectionPointTest.java
+++ b/test/com/google/inject/spi/InjectionPointTest.java
@@ -18,7 +18,6 @@
 
 import com.google.common.collect.ImmutableSet;
 import static com.google.common.collect.Iterables.getOnlyElement;
-import com.google.common.collect.Sets;
 import static com.google.inject.Asserts.assertEqualsBothWays;
 import static com.google.inject.Asserts.assertSimilarWhenReserialized;
 import com.google.inject.Inject;
@@ -31,7 +30,6 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.lang.reflect.Type;
 import java.util.Map;
 import java.util.Set;
 import junit.framework.Assert;
@@ -140,24 +138,23 @@
     Method instanceMethod = HasInjections.class.getMethod("instanceMethod", String.class);
     Field instanceField = HasInjections.class.getField("instanceField");
 
-    Set<InjectionPoint> sink = Sets.newHashSet();
-    InjectionPoint.addForInstanceMethodsAndFields(HasInjections.class, sink);
+    TypeLiteral<HasInjections> type = TypeLiteral.get(HasInjections.class);
     assertEquals(ImmutableSet.of(
-        new InjectionPoint(TypeLiteral.get(HasInjections.class), instanceMethod),
-        new InjectionPoint(TypeLiteral.get(HasInjections.class), instanceField)),
-        sink);
+        new InjectionPoint(type, instanceMethod),
+        new InjectionPoint(type, instanceField)),
+        InjectionPoint.forInstanceMethodsAndFields(HasInjections.class));
   }
 
   public void testAddForStaticMethodsAndFields() throws Exception {
     Method staticMethod = HasInjections.class.getMethod("staticMethod", String.class);
     Field staticField = HasInjections.class.getField("staticField");
 
-    Set<InjectionPoint> sink = Sets.newHashSet();
-    InjectionPoint.addForStaticMethodsAndFields(HasInjections.class, sink);
+    Set<InjectionPoint> injectionPoints = InjectionPoint.forStaticMethodsAndFields(
+        HasInjections.class);
     assertEquals(ImmutableSet.of(
         new InjectionPoint(TypeLiteral.get(HasInjections.class), staticMethod),
         new InjectionPoint(TypeLiteral.get(HasInjections.class), staticField)),
-        sink);
+        injectionPoints);
   }
 
   static class HasInjections {
@@ -168,15 +165,13 @@
   }
 
   public void testAddForParameterizedInjections() {
-    Set<InjectionPoint> sink = Sets.newHashSet();
-    Type type = new TypeLiteral<ParameterizedInjections<String>>() {}.getType();
+    TypeLiteral<?> type = new TypeLiteral<ParameterizedInjections<String>>() {};
 
     InjectionPoint constructor = InjectionPoint.forConstructorOf(type);
     assertEquals(new Key<Map<String, String>>() {},
         getOnlyElement(constructor.getDependencies()).getKey());
 
-    InjectionPoint.addForInstanceMethodsAndFields(type, sink);
-    InjectionPoint field = getOnlyElement(sink);
+    InjectionPoint field = getOnlyElement(InjectionPoint.forInstanceMethodsAndFields(type));
     assertEquals(new Key<Set<String>>() {}, getOnlyElement(field.getDependencies()).getKey());
   }