// Path: library/src/main/java/com/oasisfeng/hack/Hack.java
// public class Unchecked extends RuntimeException {}
// 
// Path: library/src/main/java/com/oasisfeng/hack/Hack.java
// public static Class<?> ANY_TYPE = $.class; private static class $ {}


import com.oasisfeng.hack.Hack.Unchecked;
import org.junit.Before;
import org.junit.Test;
import java.io.FileNotFoundException;
import java.io.IOException;
import static com.oasisfeng.hack.Hack.ANY_TYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
		final Hack.HackedMethod0<Integer, Simple, Unchecked, Unchecked, Unchecked> foo
				= Hack.into(Simple.class).method("foo").returning(int.class).withoutParams();
		assertNotNull(foo);
		assertEquals(7, (int) foo.invoke().on(simple));

		final Hack.HackedMethod0<Integer, Simple, RuntimeException, Unchecked, Unchecked> foo_rt_ex
				= Hack.into(Simple.class).method("foo").returning(int.class).throwing(RuntimeException.class).withoutParams();
		assertNotNull(foo_rt_ex);
		assertEquals(7, (int) foo_rt_ex.invoke().on(simple));

		final Hack.HackedMethod0<Integer, Simple, IOException, Unchecked, Unchecked> foo_ex
				= Hack.into(Simple.class).method("foo").returning(int.class).throwing(IOException.class).withoutParams();
		assertNotNull(foo_ex);
		assertEquals(7, (int) foo_ex.invoke().on(simple));

		final Hack.HackedMethod3<Void, Void, IOException, Unchecked, Unchecked, Integer, String, Simple> bar
				= Hack.into(Simple.class).staticMethod("bar").throwing(IOException.class).withParams(int.class, String.class, Simple.class);
		assertNotNull(bar);
		bar.invoke(-1, "xyz", simple).statically();

		assertFail(null, Hack.into(Simple.class).method("bar").throwing(UnsupportedOperationException.class, FileNotFoundException.class).withParams(int.class, String.class, Simple.class));

		assertFail(NoSuchMethodException.class, Hack.into(Simple.class).method("notExist").withoutParams());
		assertFail(NoSuchMethodException.class, Hack.into(Simple.class).method("foo").withParam(int.class));
		assertFail(null, Hack.into(Simple.class).staticMethod("foo").withoutParams());
		assertFail(null, Hack.into(Simple.class).method("foo").returning(Void.class).withoutParams());
	}

	@Test public void testMethodReturningAnyType() throws IOException {
		final Hack.HackedMethod0<?, Simple, Unchecked, Unchecked, Unchecked> foo
// Path: library/src/main/java/com/oasisfeng/hack/Hack.java
// public class Unchecked extends RuntimeException {}
// 
// Path: library/src/main/java/com/oasisfeng/hack/Hack.java
// public static Class<?> ANY_TYPE = $.class; private static class $ {}


// Path: library/src/test/java/com/oasisfeng/hack/HackTest.java
import com.oasisfeng.hack.Hack.Unchecked;
import org.junit.Before;
import org.junit.Test;
import java.io.FileNotFoundException;
import java.io.IOException;
import static com.oasisfeng.hack.Hack.ANY_TYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

		final Hack.HackedMethod0<Integer, Simple, Unchecked, Unchecked, Unchecked> foo
				= Hack.into(Simple.class).method("foo").returning(int.class).withoutParams();
		assertNotNull(foo);
		assertEquals(7, (int) foo.invoke().on(simple));

		final Hack.HackedMethod0<Integer, Simple, RuntimeException, Unchecked, Unchecked> foo_rt_ex
				= Hack.into(Simple.class).method("foo").returning(int.class).throwing(RuntimeException.class).withoutParams();
		assertNotNull(foo_rt_ex);
		assertEquals(7, (int) foo_rt_ex.invoke().on(simple));

		final Hack.HackedMethod0<Integer, Simple, IOException, Unchecked, Unchecked> foo_ex
				= Hack.into(Simple.class).method("foo").returning(int.class).throwing(IOException.class).withoutParams();
		assertNotNull(foo_ex);
		assertEquals(7, (int) foo_ex.invoke().on(simple));

		final Hack.HackedMethod3<Void, Void, IOException, Unchecked, Unchecked, Integer, String, Simple> bar
				= Hack.into(Simple.class).staticMethod("bar").throwing(IOException.class).withParams(int.class, String.class, Simple.class);
		assertNotNull(bar);
		bar.invoke(-1, "xyz", simple).statically();

		assertFail(null, Hack.into(Simple.class).method("bar").throwing(UnsupportedOperationException.class, FileNotFoundException.class).withParams(int.class, String.class, Simple.class));

		assertFail(NoSuchMethodException.class, Hack.into(Simple.class).method("notExist").withoutParams());
		assertFail(NoSuchMethodException.class, Hack.into(Simple.class).method("foo").withParam(int.class));
		assertFail(null, Hack.into(Simple.class).staticMethod("foo").withoutParams());
		assertFail(null, Hack.into(Simple.class).method("foo").returning(Void.class).withoutParams());
	}

	@Test public void testMethodReturningAnyType() throws IOException {
		final Hack.HackedMethod0<?, Simple, Unchecked, Unchecked, Unchecked> foo
				= Hack.into(Simple.class).method("foo").returning(ANY_TYPE).withoutParams();