// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/proxies/WeavedProxyFactory.java
// public interface WeavedProxyFactory {
// 
//     <T> T createWeavedProxy(final T objectToProxy, final Weaver weaverAdapter);
// 
// }
// 
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/weaving/Weaver.java
// public interface Weaver {
// 
//     /**
//      * Register an aspect to be weaved later into classes.
//      */
//     void registerAspect(Class<?> aspect);
// 
//     /**
//      * Unregister a previously registered aspect. If the given aspect was not registered, nothing is
//      * done.
//      * 
//      * @throws NotAnAspect if the class is not an aspect class.
//      * @throws NotAConcreteAspect if the aspect is an abstract aspect.
//      */
//     void unregisterAspect(Class<?> aspect);
// 
//     /**
//      * <p>
//      * Reset the weaver to a neutral state (not always the initial state).
//      * </p>
//      * <ul>
//      * <li>All registered aspects <strong>will be unregistered</strong>.</li>
//      * <li>The exact neutral state depends on the implementation. Some states and caches could be
//      * kept for performance reasons. Normally, those remainings should be safe.</li>
//      * </ul>
//      */
//     void reset();
// 
//     /**
//      * Weave a class' bytcode using all registered aspects.
//      * 
//      * @throws WeavingError An error occurs during the weaving.
//      * @return The weaved class' bytecode.
//      */
//     byte[] weaveClassBytes(String className, final byte[] bytes);
// 
// }


import info.rubico.mock4aj.api.proxies.WeavedProxyFactory;
import info.rubico.mock4aj.api.weaving.Weaver;
package info.rubico.mock4aj.internal;


/**
 * Facade to offer a simplest entry point to the proxy weaving creation process. It uses the
 * {@link WeavedProxyFactory} but hides the {@link Weaver} management.
 */
public class WeavedProxyFacade {

    private final WeavedProxyFactory proxyFactory;
    private final Weaver weaver;

    public WeavedProxyFacade(final WeavedProxyFactory proxyFactory, final Weaver weaver) {
        this.proxyFactory = proxyFactory;
        this.weaver = weaver;
    }

    public <T> T createWeavedProxy(final T objectToProxy, final Class<?>... aspectsToWeave) {
        registerOnlyThoseAspectsForWeaving(aspectsToWeave);
        return proxyFactory.createWeavedProxy(objectToProxy, weaver);
    }

    private void registerOnlyThoseAspectsForWeaving(final Class<?>[] aspectsToWeave) {
        weaver.reset();
        for (Class<?> aspectToWeave : aspectsToWeave) {
            weaver.registerAspect(aspectToWeave);
        }
    }

    protected WeavedProxyFactory getWeavedProxyFactory() {
        return proxyFactory;
    }

// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/proxies/WeavedProxyFactory.java
// public interface WeavedProxyFactory {
// 
//     <T> T createWeavedProxy(final T objectToProxy, final Weaver weaverAdapter);
// 
// }
// 
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/weaving/Weaver.java
// public interface Weaver {
// 
//     /**
//      * Register an aspect to be weaved later into classes.
//      */
//     void registerAspect(Class<?> aspect);
// 
//     /**
//      * Unregister a previously registered aspect. If the given aspect was not registered, nothing is
//      * done.
//      * 
//      * @throws NotAnAspect if the class is not an aspect class.
//      * @throws NotAConcreteAspect if the aspect is an abstract aspect.
//      */
//     void unregisterAspect(Class<?> aspect);
// 
//     /**
//      * <p>
//      * Reset the weaver to a neutral state (not always the initial state).
//      * </p>
//      * <ul>
//      * <li>All registered aspects <strong>will be unregistered</strong>.</li>
//      * <li>The exact neutral state depends on the implementation. Some states and caches could be
//      * kept for performance reasons. Normally, those remainings should be safe.</li>
//      * </ul>
//      */
//     void reset();
// 
//     /**
//      * Weave a class' bytcode using all registered aspects.
//      * 
//      * @throws WeavingError An error occurs during the weaving.
//      * @return The weaved class' bytecode.
//      */
//     byte[] weaveClassBytes(String className, final byte[] bytes);
// 
// }


// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/internal/WeavedProxyFacade.java
import info.rubico.mock4aj.api.proxies.WeavedProxyFactory;
import info.rubico.mock4aj.api.weaving.Weaver;

package info.rubico.mock4aj.internal;


/**
 * Facade to offer a simplest entry point to the proxy weaving creation process. It uses the
 * {@link WeavedProxyFactory} but hides the {@link Weaver} management.
 */
public class WeavedProxyFacade {

    private final WeavedProxyFactory proxyFactory;
    private final Weaver weaver;

    public WeavedProxyFacade(final WeavedProxyFactory proxyFactory, final Weaver weaver) {
        this.proxyFactory = proxyFactory;
        this.weaver = weaver;
    }

    public <T> T createWeavedProxy(final T objectToProxy, final Class<?>... aspectsToWeave) {
        registerOnlyThoseAspectsForWeaving(aspectsToWeave);
        return proxyFactory.createWeavedProxy(objectToProxy, weaver);
    }

    private void registerOnlyThoseAspectsForWeaving(final Class<?>[] aspectsToWeave) {
        weaver.reset();
        for (Class<?> aspectToWeave : aspectsToWeave) {
            weaver.registerAspect(aspectToWeave);
        }
    }

    protected WeavedProxyFactory getWeavedProxyFactory() {
        return proxyFactory;
    }

    protected Weaver getWeaver() {