// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/Mock4AspectJ.java
// public static synchronized <T> T createWeavedProxy(T objectToProxy,
//                                                    Class<?>... aspectsToWeave) {
//     return weavedProxyFacade.createWeavedProxy(objectToProxy, aspectsToWeave);
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/AbstractAspect.java
// @Aspect
// public abstract class AbstractAspect {
// 
//     @Pointcut
//     public abstract void abstractPc();
// 
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/ConcreteTarget.java
// public class ConcreteTarget implements Target {
// 
//     public void theMethod() {
//     }
// 
//     public void otherMethod() {
// 
//     }
// 
//     public void markWeaved(final Class<?> fromAspect) {
//     }
// 
//     public int retInt() {
//         return 0;
//     }
// 
//     public void throwingMethod() throws SomeException {
//         throw new SomeException("ConcreteTarget is throwing this");
//     }
// 
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/MarkTargetAtAspect.java
// @Aspect
// @SuppressWarnings("unused")
// public class MarkTargetAtAspect {
// 
//     @Pointcut("execution(* Target.theMethod(..)) && within(Target) && this(Target) && this(t)")
//     private void theMethodExec(Target t) { // NOPMD
//     }
// 
//     @SuppressAjWarnings
//     @After("theMethodExec(t)")
//     public void afterAMethodInTarget(Target t) { // NOPMD
//         t.markWeaved(this.getClass());
//     }
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/OtherClass.java
// public class OtherClass {
// 
//     public void doSomething() {
// 
//     }
// 
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/SecondMarkTargetAtAspect.java
// @Aspect
// @SuppressWarnings("unused")
// public class SecondMarkTargetAtAspect {
// 
//     @Pointcut("execution(* theMethod(..)) && within(Target) && this(t)")
//     private void theMethodExec(Target t) { // NOPMD
//     }
// 
//     @SuppressAjWarnings
//     @After("theMethodExec(t)")
//     public void afterAMethodInTarget(Target t) { // NOPMD
//         t.markWeaved(this.getClass());
//     }
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/Target.java
// public interface Target {
// 
//     void theMethod();
// 
//     void otherMethod();
// 
//     int retInt();
// 
//     void throwingMethod() throws SomeException;
// 
//     void markWeaved(Class<?> fromAspect);
// }
// 
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/exceptions/NotAConcreteAspect.java
// public class NotAConcreteAspect extends Mock4AjException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public NotAConcreteAspect(final String message) {
//         super(message);
//     }
// 
//     public NotAConcreteAspect(final Class<?> abstractAspect) {
//         super(String.format("A concrete aspect was expected but the aspect '%s' is abstract.\n"
//                             + "\n"
//                             + "\tTypically this error happens when you tried to weave an"
//                             + "abstract aspect. You must extend it first.", abstractAspect));
//     }
// 
// }
// 
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/exceptions/NotAnAspect.java
// public class NotAnAspect extends Mock4AjException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public NotAnAspect(final String message) {
//         super(message);
//     }
// 
//     public NotAnAspect(final Class<?> nonAspectClass) {
//         super(String.format("An aspect was expected but the class '%s' is not.", nonAspectClass));
//     }
// 
// }


import static info.rubico.mock4aj.Mock4AspectJ.createWeavedProxy;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import info.rubico.mock4aj.acceptance.testdata.AbstractAspect;
import info.rubico.mock4aj.acceptance.testdata.ConcreteTarget;
import info.rubico.mock4aj.acceptance.testdata.MarkTargetAtAspect;
import info.rubico.mock4aj.acceptance.testdata.OtherClass;
import info.rubico.mock4aj.acceptance.testdata.SecondMarkTargetAtAspect;
import info.rubico.mock4aj.acceptance.testdata.Target;
import info.rubico.mock4aj.api.exceptions.NotAConcreteAspect;
import info.rubico.mock4aj.api.exceptions.NotAnAspect;
import java.util.Date;
import org.junit.Test;
        Class<?> aspect = MarkTargetAtAspect.class;
        Target mock = mock(Target.class);

        Target proxy = createWeavedProxy(mock, aspect);
        proxy.theMethod();

        verify(mock).markWeaved(aspect); // Call by the advice and forwarded to the mock
    }

    @Test
    public void canWeaveMockOfInterfaces() {
        Class<?> anAspect = MarkTargetAtAspect.class;
        Target mock = mock(Target.class);

        Target proxy = createWeavedProxy(mock, anAspect);
        proxy.theMethod();
    }

    @Test
    public void canWeaveMockOfConcreteClasses() {
        Class<?> anAspect = MarkTargetAtAspect.class;
        Target mock = mock(ConcreteTarget.class);

        Target proxy = createWeavedProxy(mock, anAspect);
        proxy.theMethod();
    }

    @Test
    public void shouldLeaveOriginalMockUnweaved() {
        Class<?> anAspect = MarkTargetAtAspect.class;
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/Mock4AspectJ.java
// public static synchronized <T> T createWeavedProxy(T objectToProxy,
//                                                    Class<?>... aspectsToWeave) {
//     return weavedProxyFacade.createWeavedProxy(objectToProxy, aspectsToWeave);
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/AbstractAspect.java
// @Aspect
// public abstract class AbstractAspect {
// 
//     @Pointcut
//     public abstract void abstractPc();
// 
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/ConcreteTarget.java
// public class ConcreteTarget implements Target {
// 
//     public void theMethod() {
//     }
// 
//     public void otherMethod() {
// 
//     }
// 
//     public void markWeaved(final Class<?> fromAspect) {
//     }
// 
//     public int retInt() {
//         return 0;
//     }
// 
//     public void throwingMethod() throws SomeException {
//         throw new SomeException("ConcreteTarget is throwing this");
//     }
// 
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/MarkTargetAtAspect.java
// @Aspect
// @SuppressWarnings("unused")
// public class MarkTargetAtAspect {
// 
//     @Pointcut("execution(* Target.theMethod(..)) && within(Target) && this(Target) && this(t)")
//     private void theMethodExec(Target t) { // NOPMD
//     }
// 
//     @SuppressAjWarnings
//     @After("theMethodExec(t)")
//     public void afterAMethodInTarget(Target t) { // NOPMD
//         t.markWeaved(this.getClass());
//     }
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/OtherClass.java
// public class OtherClass {
// 
//     public void doSomething() {
// 
//     }
// 
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/SecondMarkTargetAtAspect.java
// @Aspect
// @SuppressWarnings("unused")
// public class SecondMarkTargetAtAspect {
// 
//     @Pointcut("execution(* theMethod(..)) && within(Target) && this(t)")
//     private void theMethodExec(Target t) { // NOPMD
//     }
// 
//     @SuppressAjWarnings
//     @After("theMethodExec(t)")
//     public void afterAMethodInTarget(Target t) { // NOPMD
//         t.markWeaved(this.getClass());
//     }
// }
// 
// Path: mock4aj-acceptancetests/src/main/java/info/rubico/mock4aj/acceptance/testdata/Target.java
// public interface Target {
// 
//     void theMethod();
// 
//     void otherMethod();
// 
//     int retInt();
// 
//     void throwingMethod() throws SomeException;
// 
//     void markWeaved(Class<?> fromAspect);
// }
// 
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/exceptions/NotAConcreteAspect.java
// public class NotAConcreteAspect extends Mock4AjException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public NotAConcreteAspect(final String message) {
//         super(message);
//     }
// 
//     public NotAConcreteAspect(final Class<?> abstractAspect) {
//         super(String.format("A concrete aspect was expected but the aspect '%s' is abstract.\n"
//                             + "\n"
//                             + "\tTypically this error happens when you tried to weave an"
//                             + "abstract aspect. You must extend it first.", abstractAspect));
//     }
// 
// }
// 
// Path: mock4aj-core/src/main/java/info/rubico/mock4aj/api/exceptions/NotAnAspect.java
// public class NotAnAspect extends Mock4AjException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public NotAnAspect(final String message) {
//         super(message);
//     }
// 
//     public NotAnAspect(final Class<?> nonAspectClass) {
//         super(String.format("An aspect was expected but the class '%s' is not.", nonAspectClass));
//     }
// 
// }


// Path: mock4aj-acceptancetests/src/test/java/info/rubico/mock4aj/acceptance/CreateWeavedProxiesOfExistingMocksAccTest.java
import static info.rubico.mock4aj.Mock4AspectJ.createWeavedProxy;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import info.rubico.mock4aj.acceptance.testdata.AbstractAspect;
import info.rubico.mock4aj.acceptance.testdata.ConcreteTarget;
import info.rubico.mock4aj.acceptance.testdata.MarkTargetAtAspect;
import info.rubico.mock4aj.acceptance.testdata.OtherClass;
import info.rubico.mock4aj.acceptance.testdata.SecondMarkTargetAtAspect;
import info.rubico.mock4aj.acceptance.testdata.Target;
import info.rubico.mock4aj.api.exceptions.NotAConcreteAspect;
import info.rubico.mock4aj.api.exceptions.NotAnAspect;
import java.util.Date;
import org.junit.Test;

        Class<?> aspect = MarkTargetAtAspect.class;
        Target mock = mock(Target.class);

        Target proxy = createWeavedProxy(mock, aspect);
        proxy.theMethod();

        verify(mock).markWeaved(aspect); // Call by the advice and forwarded to the mock
    }

    @Test
    public void canWeaveMockOfInterfaces() {
        Class<?> anAspect = MarkTargetAtAspect.class;
        Target mock = mock(Target.class);

        Target proxy = createWeavedProxy(mock, anAspect);
        proxy.theMethod();
    }

    @Test
    public void canWeaveMockOfConcreteClasses() {
        Class<?> anAspect = MarkTargetAtAspect.class;
        Target mock = mock(ConcreteTarget.class);

        Target proxy = createWeavedProxy(mock, anAspect);
        proxy.theMethod();
    }

    @Test
    public void shouldLeaveOriginalMockUnweaved() {
        Class<?> anAspect = MarkTargetAtAspect.class;
        Target mock = mock(ConcreteTarget.class);