class BeanFactoryTransformer {

    private static final AgentLogger LOGGER = AgentLogger.getLogger(BeanFactoryTransformer.class);

    @OnClassLoadEvent(classNameRegexp = "org.springframework.beans.factory.support.DefaultSingletonBeanRegistry")
    public static void registerDefaultSingletonBeanRegistry(ClassLoader appClassLoader, CtClass clazz,
        ClassPool classPool) throws NotFoundException, CannotCompileException {
        clazz.addField(
            CtField.make("private java.util.Set hotswapAgent$destroyBean = new java.util.HashSet();", clazz));
        clazz.addInterface(classPool.get("org.hotswap.agent.plugin.spring.transformers.api.BeanFactoryLifecycle"));
        clazz.addMethod(CtNewMethod.make(
            "public boolean hotswapAgent$isDestroyedBean(String beanName) { return hotswapAgent$destroyBean.contains"
                + "(beanName); }",
            clazz));
        clazz.addMethod(CtNewMethod.make(
            "public void hotswapAgent$destroyBean(String beanName) { hotswapAgent$destroyBean.add(beanName); }",
            clazz));
        clazz.addMethod(
            CtNewMethod.make("public void hotswapAgent$clearDestroyBean() { hotswapAgent$destroyBean.clear(); }",
                clazz));

        CtMethod destroySingletonMethod = clazz.getDeclaredMethod("destroySingleton",
            new CtClass[] {classPool.get(String.class.getName())});
        destroySingletonMethod.insertAfter(
            BeanFactoryProcessor.class.getName() + ".postProcessDestroySingleton($0, $1);");
    }

    @OnClassLoadEvent(classNameRegexp = "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory")
    public static void registerAbstractAutowireCapableBeanFactory(ClassLoader appClassLoader, CtClass clazz,
        ClassPool classPool) throws NotFoundException, CannotCompileException {<FILL_FUNCTION_BODY>}
}

        clazz.addField(CtField.make("private static final org.hotswap.agent.logging.AgentLogger $$ha$LOGGER = " +
                "org.hotswap.agent.logging.AgentLogger.getLogger(org.springframework.beans.factory.annotation"
                + ".InitDestroyAnnotationBeanPostProcessor.class);",
            clazz));

        CtMethod createBeanMethod = clazz.getDeclaredMethod("createBean", new CtClass[] {
            classPool.get(String.class.getName()),
            classPool.get("org.springframework.beans.factory.support.RootBeanDefinition"),
            classPool.get(Object[].class.getName())});
        createBeanMethod.insertAfter(BeanFactoryProcessor.class.getName() + ".postProcessCreateBean($0, $1, $2);");

        // try catch for custom init method
        CtMethod[] invokeCustomInitMethods = clazz.getDeclaredMethods("invokeCustomInitMethod");
        if (invokeCustomInitMethods.length != 1) {
            LOGGER.error("Unexpected number of 'invokeCustomInitMethod' methods found. Expected: 1, Found: " + invokeCustomInitMethods.length);
        }
        invokeCustomInitMethods[0].addCatch(
            InitMethodEnhance.catchException("$2", "$$ha$LOGGER", "$e", "invokeCustomInitMethod", false),
            classPool.get("java.lang.Throwable"));

        // try catch for afterPropertiesSet
        CtMethod invokeInitMethod = clazz.getDeclaredMethod("invokeInitMethods",
            new CtClass[] {classPool.get(String.class.getName()), classPool.get("java.lang.Object"),
                classPool.get("org.springframework.beans.factory.support.RootBeanDefinition")});
        invokeInitMethod.addCatch(
            InitMethodEnhance.catchException("$2", "$$ha$LOGGER", "$e", "invokeInitMethods", false),
            classPool.get("java.lang.Throwable"));
    
<no_super_class>