docs: public static Set<Key<?>> getAllUnboundKeys(List<Element> elements) {
          final Set<Key<?>> boundKeys = new HashSet<>();
          for (Element element : elements) {
              element.acceptVisitor(new DefaultElementVisitor<Void>() {
                  public <T> Void visit(Binding<T> binding) {
                      boundKeys.add(binding.getKey());
                      return null;
                  }
              });
          }
  
          final Set<Key<?>> foundKeys = new HashSet<>();
          
          for (Element element : elements) {
              element.acceptVisitor(new DefaultElementVisitor<Void>() {
                  @Override
                  public <T> Void visit(Binding<T> binding) {
                      binding.acceptTargetVisitor(new DefaultBindingTargetVisitor<T, Void>() {
                          @Override
                          public Void visit(ProviderKeyBinding<? extends T> binding) {
                              addFoundKeys(getUnboundDirectDependencies(binding.getProviderKey().getTypeLiteral(), boundKeys));
                              return null;
                          }
  
                          @Override
                          public Void visit(LinkedKeyBinding<? extends T> binding) {
                              if (!boundKeys.contains(binding.getLinkedKey())) {
                                  addFoundKeys(getUnboundDirectDependencies(binding.getLinkedKey().getTypeLiteral(), boundKeys));
                              }
                              return null;
                          }
  
                          @Override
                          public Void visit(UntargettedBinding<? extends T> binding) {
                              addFoundKeys(getUnboundDirectDependencies(binding.getKey().getTypeLiteral(), boundKeys));
                              return null;
                          }
  
                          @Override
                          public Void visit(ConstructorBinding<? extends T> binding) {
                              addFoundKeys(getUnboundDirectDependencies(binding.getInjectableMembers(), boundKeys));
                              addFoundKeys(getUnboundDirectDependencies(binding.getDependencies(), boundKeys));
                              return null;
                          }
  
                          @Override
                          public Void visit(ProviderBinding<? extends T> binding) {
                              addFoundKeys(getUnboundDirectDependencies(binding.getProvidedKey().getTypeLiteral(), boundKeys));
                              return null;
                          }
                          
                          private void addFoundKeys(Set<Key<?>> keys) {
                              foundKeys.addAll(keys);
                          }
                      });
                      return null;
                  }
  
                  /**
                   * Visit a request to inject the instance fields and methods of an instance.
                   */
                  @Override
                  public Void visit(InjectionRequest<?> request) {
                      for (InjectionPoint ip : request.getInjectionPoints()) {
                          for (Dependency<?> dep : ip.getDependencies()) {
                              foundKeys.addAll(getUnboundDirectDependencies(dep.getKey().getTypeLiteral(), boundKeys));
                          }
                      }
                      return null;
                  }
  
                  /**
                   * Visit a request to inject the static fields and methods of type.
                   */
                  @Override
                  public Void visit(StaticInjectionRequest request) {
                      for (InjectionPoint ip : request.getInjectionPoints()) {
                          for (Dependency<?> dep : ip.getDependencies()) {
                              foundKeys.addAll(getUnboundDirectDependencies(dep.getKey().getTypeLiteral(), boundKeys));
                          }
                      }
                      return null;
                  }
  
                  
                  /**
                   * Visit a lookup of the provider for a type.
                   */
                  @Override
                  public <T> Void visit(ProviderLookup<T> lookup) {
                      foundKeys.add(lookup.getDependency().getKey());
                      return null;
                  }
              });
          }
          
          // Recursively look at the final list of unbound keys to further discover dependencies
          // and exclude keys that may be instantiated using the JIT
          for (Key<?> key : foundKeys) {
              discoverDependencies(key, boundKeys);
          }
          foundKeys.removeAll(boundKeys);
          foundKeys.remove(Key.get(Injector.class));
          return foundKeys;
      }