docs: @Beta
      public static Injector bootstrap(final Class<?> main, final Module externalBindings, final BootstrapModule... externalBootstrapModules) {
          
          final LifecycleInjectorBuilder builder = LifecycleInjector.builder();
          
          // Create a temporary Guice injector for the purpose of constructing the list of
          // BootstrapModules which can inject any of the bootstrap annotations as well as 
          // the externally provided bindings.
          // Creation order,
          // 1.  Construct all BootstrapModule classes
          // 2.  Inject external bindings into BootstrapModule instances
          // 3.  Create the bootstrap injector with these modules
          Injector injector = Guice.createInjector(new AbstractModule() {
              @SuppressWarnings({ "unchecked", "rawtypes" })
              @Override
              protected void configure() {
                  if (externalBindings != null)
                      install(externalBindings);
                  
                  Multibinder<BootstrapModule> bootstrapModules = Multibinder.newSetBinder(binder(), BootstrapModule.class);
                  Multibinder<LifecycleInjectorBuilderSuite> suites = Multibinder.newSetBinder(binder(), LifecycleInjectorBuilderSuite.class);
                  
                  if (externalBootstrapModules != null) {
                      for (final BootstrapModule bootstrapModule : externalBootstrapModules) {
                          bootstrapModules
                              .addBinding()
                              .toProvider(new MemberInjectingInstanceProvider<BootstrapModule>(bootstrapModule));
                      }
                  }
  
                  // Iterate through all annotations of the main class and convert them into
                  // their BootstrapModules
                  for (final Annotation annot : main.getDeclaredAnnotations()) {
                      final Class<? extends Annotation> type = annot.annotationType();
                      LOG.info("Found bootstrap annotation {}", type.getName());
                      Bootstrap bootstrap = type.getAnnotation(Bootstrap.class);
                      if (bootstrap != null) {
                      	boolean added = false;
                      	// This is a suite
                      	if (!bootstrap.value().equals(Bootstrap.NullLifecycleInjectorBuilderSuite.class)) {
                              LOG.info("Adding Suite {}", bootstrap.bootstrap());
                      		suites
  	                            .addBinding()
  	                            .to(bootstrap.value())
  	                            .asEagerSingleton();
                      		added = true;
                      	}
                      	// This is a bootstrap module
                      	if (!bootstrap.bootstrap().equals(Bootstrap.NullBootstrapModule.class)) {
                      		Preconditions.checkState(added==false, "%s already added as a LifecycleInjectorBuilderSuite", bootstrap.annotationType().getName());
                      		added = true;
                              LOG.info("Adding BootstrapModule {}", bootstrap.bootstrap());
  	                        bootstrapModules
  	                            .addBinding()
  	                            .to(bootstrap.bootstrap())
  	                            .asEagerSingleton();
  	                        // Make this annotation injectable into any plain Module
  	                        builder.withAdditionalBootstrapModules(forAnnotation(annot));
                      	}
                      	// This is a plain guice module
                      	if (!bootstrap.module().equals(Bootstrap.NullModule.class)) {
                      		Preconditions.checkState(added==false, "%s already added as a BootstrapModule", bootstrap.annotationType().getName());
                      		added = true;
                              LOG.info("Adding Module {}", bootstrap.bootstrap());
  	                        builder.withAdditionalModuleClasses(bootstrap.module());
  	                        // Make the annotation injectable into the module
  	                        builder.withAdditionalBootstrapModules(forAnnotation(annot));
                      	}
                              
                          // Makes the annotation injectable into LifecycleInjectorBuilderSuite
                          bind(Key.get(type))
                              .toProvider(new Provider() {
                                  @Override
                                  public Object get() {
                                      return annot;
                                  }
                              })
                              .in(Scopes.SINGLETON);
                      }
                  }
              }
          });
          
          // First, give all LifecycleInjectorBuilderSuite's priority 
          Set<LifecycleInjectorBuilderSuite> suites = injector.getInstance(Key.get(new TypeLiteral<Set<LifecycleInjectorBuilderSuite>>() {}));
          for (LifecycleInjectorBuilderSuite suite : suites) {
          	suite.configure(builder);
          }
          
          // Next, install BootstrapModule's
          builder.withAdditionalBootstrapModules(injector.getInstance(Key.get(new TypeLiteral<Set<BootstrapModule>>() {})));
          
          // The main class is added last so it can override any bindings from the BootstrapModule's and LifecycleInjectorBuilderSuite's
          if (Module.class.isAssignableFrom(main)) {
              try {
                  builder.withAdditionalModuleClasses(main);
              } catch (Exception e) {
                  throw new ProvisionException(String.format("Failed to create module for main class '%s'", main.getName()), e);
              }
          }
          
          // Finally, create and return the injector
          return builder.build().createInjector();
      }