// Path: asteroid-core/src/main/java/asteroid/utils/InternalUtils.java
// public static <T> List<T> collect(final Object iterable, final Closure<T> process) {
//     if (iterable == null) {
//         return new ArrayList<>();
//     }
// 
//     return DefaultGroovyMethods.collect(iterable, process);
// }
// 
// Path: asteroid-core/src/main/java/asteroid/transformer/AbstractMethodNodeTransformer.java
// public abstract class AbstractMethodNodeTransformer extends AbstractTransformer {
// 
//     private final Closure<Boolean> criteria;
// 
//     /**
//      * Every instance needs the source unit and the name of the class
//      * it's going to transform.
//      *
//      * To find methods eligible to be transformed by this {@link Transformer}
//      * a {@link Closure} returning a boolean is used as a criteria.
//      *
//      * You can create your own criteria or use one of the static
//      * methods present in this class. These methods will create a
//      * pre-defined criteria.
//      *
//      * The {@link Closure} used as a criteria will receive a {@link
//      * MethodNode} and return a {@link Boolean} value. If the closure
//      * returns true then the transformation will be apply, if not the
//      * {@link MethodNode} will be discarded.
//      *
//      * @deprecated
//      * @param sourceUnit Needed to apply scope
//      * @param criteria used to locate target classes
//      * look for the qualified method)
//      * @since 0.2.0
//      * @see asteroid.Criterias#byMethodNodeNameContains(String)
//      */
//     public AbstractMethodNodeTransformer(final SourceUnit sourceUnit, final Closure<Boolean> criteria) {
//         super(sourceUnit);
//         this.criteria = criteria;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void visitMethod(final MethodNode methodNode) {
//         if (methodNode == null || !this.criteria.call(methodNode)) {
//             return;
//         }
// 
//         transformMethod(methodNode);
//     }
// 
//     /**
//      * Within this method developer could modify the {@link MethodNode}
//      * instance.
//      *
//      * @param methodNode the {@link MethodNode}  you want to transform
//      * @since 0.2.0
//      */
//     public abstract void transformMethod(MethodNode methodNode);
// 
// }
// 
// Path: asteroid-core/src/main/java/asteroid/transformer/AbstractClassNodeTransformer.java
// public abstract class AbstractClassNodeTransformer extends AbstractTransformer {
// 
//     private final Closure<Boolean> criteria;
// 
//     /**
//      * Every instance needs the source unit and the name of the class
//      * it's going to transform.
//      *
//      * To find classes eligible to be transformed by this {@link Transformer}
//      * a {@link Closure} returning a boolean is used as a criteria.
//      *
//      * You can create your own criteria or use one of the static
//      * methods present in this class. These methods will create a
//      * pre-defined criteria.
//      *
//      * The {@link Closure} used as a criteria will receive a {@link
//      * ClassNode} and return a {@link Boolean} value. If the closure
//      * returns true then the transformation will be apply, if not the
//      * {@link ClassNode} will be discarded.
//      *
//      * @param sourceUnit Needed to apply scope
//      * @param criteria used to locate target classes
//      * look for the qualified class)
//      * @since 0.2.0
//      * @see asteroid.Criterias#byClassNodeNameContains(String)
//      */
//     public AbstractClassNodeTransformer(final SourceUnit sourceUnit, final Closure<Boolean> criteria) {
//         super(sourceUnit);
//         this.criteria = criteria;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void visitClass(final ClassNode classNode) {
//         if (classNode == null || !this.criteria.call(classNode)) {
//             return;
//         }
// 
//         transformClass(classNode);
//     }
// 
//     /**
//      * Within this method developer could modify the {@link ClassNode}
//      * instance.
//      *
//      * @param classNode the {@link ClassNode}  you want to transform
//      * @since 0.2.0
//      */
//     public abstract void transformClass(final ClassNode classNode);
// 
// }


import static org.codehaus.groovy.runtime.DefaultGroovyMethods.any;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.every;
import static asteroid.utils.InternalUtils.collect;
import groovy.lang.Closure;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import asteroid.transformer.AbstractMethodNodeTransformer;
import asteroid.transformer.AbstractClassNodeTransformer;
import java.util.List;
        return byExprMethodCallByArgs(collect(argTypes, toClassNode()).toArray(new ClassNode[argTypes.length]));
    }

    private static Closure<ClassNode> toClassNode() {
        return new Closure<ClassNode>(null) {
            ClassNode doCall(final Class clazz) {
                return A.NODES.clazz(clazz).build();
            }
        };
    }

    /**
     * This method returns a criteria to look for {@link
     * MethodCallExpression} with arguments with the types specified
     * as parameters
     *
     * @param args the classes of every parameter
     * @return a search criteria
     * @since 0.2.9
     */
    private static Closure<Boolean> byExprMethodCallByArgs(final ClassNode... argTypes) {
        return new Closure<Boolean>(null) {
            public Boolean doCall(final Expression expression) {
                if (!(expression instanceof MethodCallExpression)) {
                    return false;
                }

                final MethodCallExpression expr = (MethodCallExpression) expression;
                final List<Expression> args = A.UTIL.EXPR
                    .getArgumentList(expr)
// Path: asteroid-core/src/main/java/asteroid/utils/InternalUtils.java
// public static <T> List<T> collect(final Object iterable, final Closure<T> process) {
//     if (iterable == null) {
//         return new ArrayList<>();
//     }
// 
//     return DefaultGroovyMethods.collect(iterable, process);
// }
// 
// Path: asteroid-core/src/main/java/asteroid/transformer/AbstractMethodNodeTransformer.java
// public abstract class AbstractMethodNodeTransformer extends AbstractTransformer {
// 
//     private final Closure<Boolean> criteria;
// 
//     /**
//      * Every instance needs the source unit and the name of the class
//      * it's going to transform.
//      *
//      * To find methods eligible to be transformed by this {@link Transformer}
//      * a {@link Closure} returning a boolean is used as a criteria.
//      *
//      * You can create your own criteria or use one of the static
//      * methods present in this class. These methods will create a
//      * pre-defined criteria.
//      *
//      * The {@link Closure} used as a criteria will receive a {@link
//      * MethodNode} and return a {@link Boolean} value. If the closure
//      * returns true then the transformation will be apply, if not the
//      * {@link MethodNode} will be discarded.
//      *
//      * @deprecated
//      * @param sourceUnit Needed to apply scope
//      * @param criteria used to locate target classes
//      * look for the qualified method)
//      * @since 0.2.0
//      * @see asteroid.Criterias#byMethodNodeNameContains(String)
//      */
//     public AbstractMethodNodeTransformer(final SourceUnit sourceUnit, final Closure<Boolean> criteria) {
//         super(sourceUnit);
//         this.criteria = criteria;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void visitMethod(final MethodNode methodNode) {
//         if (methodNode == null || !this.criteria.call(methodNode)) {
//             return;
//         }
// 
//         transformMethod(methodNode);
//     }
// 
//     /**
//      * Within this method developer could modify the {@link MethodNode}
//      * instance.
//      *
//      * @param methodNode the {@link MethodNode}  you want to transform
//      * @since 0.2.0
//      */
//     public abstract void transformMethod(MethodNode methodNode);
// 
// }
// 
// Path: asteroid-core/src/main/java/asteroid/transformer/AbstractClassNodeTransformer.java
// public abstract class AbstractClassNodeTransformer extends AbstractTransformer {
// 
//     private final Closure<Boolean> criteria;
// 
//     /**
//      * Every instance needs the source unit and the name of the class
//      * it's going to transform.
//      *
//      * To find classes eligible to be transformed by this {@link Transformer}
//      * a {@link Closure} returning a boolean is used as a criteria.
//      *
//      * You can create your own criteria or use one of the static
//      * methods present in this class. These methods will create a
//      * pre-defined criteria.
//      *
//      * The {@link Closure} used as a criteria will receive a {@link
//      * ClassNode} and return a {@link Boolean} value. If the closure
//      * returns true then the transformation will be apply, if not the
//      * {@link ClassNode} will be discarded.
//      *
//      * @param sourceUnit Needed to apply scope
//      * @param criteria used to locate target classes
//      * look for the qualified class)
//      * @since 0.2.0
//      * @see asteroid.Criterias#byClassNodeNameContains(String)
//      */
//     public AbstractClassNodeTransformer(final SourceUnit sourceUnit, final Closure<Boolean> criteria) {
//         super(sourceUnit);
//         this.criteria = criteria;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void visitClass(final ClassNode classNode) {
//         if (classNode == null || !this.criteria.call(classNode)) {
//             return;
//         }
// 
//         transformClass(classNode);
//     }
// 
//     /**
//      * Within this method developer could modify the {@link ClassNode}
//      * instance.
//      *
//      * @param classNode the {@link ClassNode}  you want to transform
//      * @since 0.2.0
//      */
//     public abstract void transformClass(final ClassNode classNode);
// 
// }


// Path: asteroid-core/src/main/java/asteroid/Criterias.java
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.any;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.every;
import static asteroid.utils.InternalUtils.collect;
import groovy.lang.Closure;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import asteroid.transformer.AbstractMethodNodeTransformer;
import asteroid.transformer.AbstractClassNodeTransformer;
import java.util.List;

        return byExprMethodCallByArgs(collect(argTypes, toClassNode()).toArray(new ClassNode[argTypes.length]));
    }

    private static Closure<ClassNode> toClassNode() {
        return new Closure<ClassNode>(null) {
            ClassNode doCall(final Class clazz) {
                return A.NODES.clazz(clazz).build();
            }
        };
    }

    /**
     * This method returns a criteria to look for {@link
     * MethodCallExpression} with arguments with the types specified
     * as parameters
     *
     * @param args the classes of every parameter
     * @return a search criteria
     * @since 0.2.9
     */
    private static Closure<Boolean> byExprMethodCallByArgs(final ClassNode... argTypes) {
        return new Closure<Boolean>(null) {
            public Boolean doCall(final Expression expression) {
                if (!(expression instanceof MethodCallExpression)) {
                    return false;
                }

                final MethodCallExpression expr = (MethodCallExpression) expression;
                final List<Expression> args = A.UTIL.EXPR
                    .getArgumentList(expr)
                    .getExpressions();