FactoryManager { public L start(RootFactoryWrapper<R> newFactory){ FactoryBase<?,?> factoryBaseInFocus=null; try { currentFactoryRoot =newFactory; Collection<FactoryBase<?,R>> factoriesInCreateAndStartOrder = newFactory.getFactoriesInCreateAndStartOrder(); for (FactoryBase<?,?> factory : factoriesInCreateAndStartOrder) { factoryBaseInFocus=factory; factory.internal().instance(); } for (FactoryBase<?,?> factory : factoriesInCreateAndStartOrder) { factoryBaseInFocus=factory; factory.internal().start(); } logger.info(currentFactoryRoot.logStartDisplayTextDeep()); return currentFactoryRoot.getRoot().internal().getLiveObject(); } catch (Exception e){ factoryExceptionHandler.startException(e,factoryBaseInFocus,new ExceptionResponseAction<>(this,null,currentFactoryRoot,new ArrayList<>())); return null; } } FactoryManager(FactoryExceptionHandler<L,R> factoryExceptionHandler); FactoryUpdateLog<R> update(R commonVersion , R newVersion, Function<String,Boolean> permissionChecker); MergeDiffInfo<R> simulateUpdate(R commonVersion , R newVersion,  Function<String, Boolean> permissionChecker); R getCurrentFactory(); L start(RootFactoryWrapper<R> newFactory); void stop(); void resetAfterCrash(); boolean isStarted();  }
@Test public void test(){ FactoryManager<ExampleLiveObjectA, ExampleFactoryA> factoryManager = new FactoryManager<ExampleLiveObjectA, ExampleFactoryA>(new RethrowingFactoryExceptionHandler<>()); ArrayList<String> calls =new ArrayList<>(); ExampleFactoryA exampleFactoryA = new ExampleFactoryA(); exampleFactoryA.configLifeCycle().setStarter(exampleLiveObjectA -> calls.add("start exampleFactoryA")); ExampleFactoryB exampleFactoryB = new ExampleFactoryB(); exampleFactoryB.configLifeCycle().setStarter(exampleLiveObjectA -> calls.add("start exampleFactoryB")); exampleFactoryA.referenceAttribute.set(exampleFactoryB); factoryManager.start(new RootFactoryWrapper<>(exampleFactoryA)); Assertions.assertEquals(2,calls.size()); Assertions.assertEquals("start exampleFactoryB",calls.get(0)); Assertions.assertEquals("start exampleFactoryA",calls.get(1)); }