// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/processing/BoundProcessor.java
// public class BoundProcessor extends AbstractAnnotationProcessor<Bound, CtParameter<?>> {
// 	public void process(Bound annotation, CtParameter<?> element) {
// 		final CtMethod parent = element.getParent(CtMethod.class);
// 
// 		// Build if check for min.
// 		CtIf anIf = getFactory().Core().createIf();
// 		anIf.setCondition(getFactory().Code().<Boolean>createCodeSnippetExpression(element.getSimpleName() + " < " + annotation.min()));
// 		CtThrow throwStmt = getFactory().Core().createThrow();
// 		throwStmt.setThrownExpression((CtExpression<? extends Throwable>) getFactory().Core().createCodeSnippetExpression().setValue("new RuntimeException(\"out of min bound (\" + " + element.getSimpleName() + " + \" < " + annotation.min() + "\")"));
// 		anIf.setThenStatement(throwStmt);
// 		parent.getBody().insertBegin(anIf);
// 		anIf.setParent(parent);
// 
// 		// Build if check for max.
// 		anIf = getFactory().Core().createIf();
// 		anIf.setCondition(getFactory().Code().<Boolean>createCodeSnippetExpression(element.getSimpleName() + " > " + annotation.max()));
// 		anIf.setThenStatement(getFactory().Code().createCtThrow("new RuntimeException(\"out of max bound (\" + " + element.getSimpleName() + " + \" > " + annotation.max() + "\")"));
// 		parent.getBody().insertBegin(anIf);
// 		anIf.setParent(parent);
// 	}
// }
// 
// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/processing/BoundTemplateProcessor.java
// public class BoundTemplateProcessor extends AbstractAnnotationProcessor<Bound, CtParameter<?>> {
// 
// 	public void process(Bound annotation, CtParameter<?> element) {
// 		// Is to be process?
// 		CtExecutable<?> e = element.getParent();
// 		if (e.getBody() == null) {
// 			return;
// 		}
// 
// 		// Use template.
// 		CtClass<?> type = e.getParent(CtClass.class);
// 		Template t = new BoundTemplate(getFactory().Type().createReference(Double.class), element.getSimpleName(), annotation.min(), annotation.max());
// 		final CtBlock apply = (CtBlock) t.apply(type);
// 
// 		// Apply transformation.
// 		for (int i = apply.getStatements().size() - 1; i >= 0; i--) {
// 			final CtStatement statement = apply.getStatement(i);
// 			statement.delete();
// 			e.getBody().insertBegin(statement);
// 		}
// 	}
// }
// 
// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/src/Main.java
// public class Main {
// 
// 	public static void main(String[] args) {
// 		for (int i = 0; i < 10; i++) {
// 			try {
// 				new Main().m(i);
// 			} catch (RuntimeException e) {
// 				System.out.println(e.getMessage());
// 			}
// 		}
// 	}
// 
// 	public void m(@Bound(min = 2d, max = 8d) int a) {
// 		System.out.println("Great method!");
// 	}
// 
// }


import fr.inria.gforge.spoon.transformation.bound.processing.BoundProcessor;
import fr.inria.gforge.spoon.transformation.bound.processing.BoundTemplateProcessor;
import fr.inria.gforge.spoon.transformation.bound.src.Main;
import org.junit.Test;
import spoon.Launcher;
import spoon.SpoonAPI;
import spoon.reflect.code.CtIf;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import static org.junit.Assert.assertTrue;
package fr.inria.gforge.spoon.transformation.bound;



public class BoundTest {
	@Test
	public void testBoundTemplate() throws Exception {
		SpoonAPI launcher = new Launcher();
		launcher.getEnvironment().setNoClasspath(true);
		launcher.addInputResource("./src/main/java");
		launcher.setSourceOutputDirectory("./target/spoon-template");
		launcher.addProcessor(new BoundTemplateProcessor());
		launcher.run();

// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/processing/BoundProcessor.java
// public class BoundProcessor extends AbstractAnnotationProcessor<Bound, CtParameter<?>> {
// 	public void process(Bound annotation, CtParameter<?> element) {
// 		final CtMethod parent = element.getParent(CtMethod.class);
// 
// 		// Build if check for min.
// 		CtIf anIf = getFactory().Core().createIf();
// 		anIf.setCondition(getFactory().Code().<Boolean>createCodeSnippetExpression(element.getSimpleName() + " < " + annotation.min()));
// 		CtThrow throwStmt = getFactory().Core().createThrow();
// 		throwStmt.setThrownExpression((CtExpression<? extends Throwable>) getFactory().Core().createCodeSnippetExpression().setValue("new RuntimeException(\"out of min bound (\" + " + element.getSimpleName() + " + \" < " + annotation.min() + "\")"));
// 		anIf.setThenStatement(throwStmt);
// 		parent.getBody().insertBegin(anIf);
// 		anIf.setParent(parent);
// 
// 		// Build if check for max.
// 		anIf = getFactory().Core().createIf();
// 		anIf.setCondition(getFactory().Code().<Boolean>createCodeSnippetExpression(element.getSimpleName() + " > " + annotation.max()));
// 		anIf.setThenStatement(getFactory().Code().createCtThrow("new RuntimeException(\"out of max bound (\" + " + element.getSimpleName() + " + \" > " + annotation.max() + "\")"));
// 		parent.getBody().insertBegin(anIf);
// 		anIf.setParent(parent);
// 	}
// }
// 
// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/processing/BoundTemplateProcessor.java
// public class BoundTemplateProcessor extends AbstractAnnotationProcessor<Bound, CtParameter<?>> {
// 
// 	public void process(Bound annotation, CtParameter<?> element) {
// 		// Is to be process?
// 		CtExecutable<?> e = element.getParent();
// 		if (e.getBody() == null) {
// 			return;
// 		}
// 
// 		// Use template.
// 		CtClass<?> type = e.getParent(CtClass.class);
// 		Template t = new BoundTemplate(getFactory().Type().createReference(Double.class), element.getSimpleName(), annotation.min(), annotation.max());
// 		final CtBlock apply = (CtBlock) t.apply(type);
// 
// 		// Apply transformation.
// 		for (int i = apply.getStatements().size() - 1; i >= 0; i--) {
// 			final CtStatement statement = apply.getStatement(i);
// 			statement.delete();
// 			e.getBody().insertBegin(statement);
// 		}
// 	}
// }
// 
// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/src/Main.java
// public class Main {
// 
// 	public static void main(String[] args) {
// 		for (int i = 0; i < 10; i++) {
// 			try {
// 				new Main().m(i);
// 			} catch (RuntimeException e) {
// 				System.out.println(e.getMessage());
// 			}
// 		}
// 	}
// 
// 	public void m(@Bound(min = 2d, max = 8d) int a) {
// 		System.out.println("Great method!");
// 	}
// 
// }


// Path: src/main/java/fr/inria/gforge/spoon/transformation/bound/BoundTest.java
import fr.inria.gforge.spoon.transformation.bound.processing.BoundProcessor;
import fr.inria.gforge.spoon.transformation.bound.processing.BoundTemplateProcessor;
import fr.inria.gforge.spoon.transformation.bound.src.Main;
import org.junit.Test;
import spoon.Launcher;
import spoon.SpoonAPI;
import spoon.reflect.code.CtIf;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import static org.junit.Assert.assertTrue;

package fr.inria.gforge.spoon.transformation.bound;



public class BoundTest {
	@Test
	public void testBoundTemplate() throws Exception {
		SpoonAPI launcher = new Launcher();
		launcher.getEnvironment().setNoClasspath(true);
		launcher.addInputResource("./src/main/java");
		launcher.setSourceOutputDirectory("./target/spoon-template");
		launcher.addProcessor(new BoundTemplateProcessor());
		launcher.run();

		final CtType<Main> target = launcher.getFactory().Type().get(Main.class);