import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

/**
 * @author Anastasiya Solodkaya.
 */
public class Failures0 {
    private static final MethodHandle EXAMPLE_COUNTER = MethodHandles.constant(int.class, 13);
    private static final MethodHandle ZERO_COUNTER = MethodHandles.constant(int.class, 0);

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException {
        LambdamanWithNullInit example = new LambdamanWithNullInit("Lambdaman!");
        MethodHandle loop = MethodHandles.countedLoop(ZERO_COUNTER, EXAMPLE_COUNTER, null, example.stepHandle());
        assertEquals(loop.type().returnType(), void.class);
    }

    static void assertEquals(Object o, Object o1) {
        assertEquals(o, o1, "Fail: " + o + " vs " + o1);
    }

    private static void assertEquals(Object o, Object o1, String s) {
        assertEquals(o, o1, s + "\nFail: " + o + " vs " + o1, null);
    }

    public static void fail(String s) {
        throw new RuntimeException(s);
    }

    public static void assertEquals(Object var0, Object var1, String var2, Throwable var3) {
        if (var0 == null) {
            if (var1 != null) {
                throw new RuntimeException(var2, var3);
            }
        } else if (!var0.equals(var1)) {
            throw new RuntimeException(var2, var3);
        }

    }

    static class LambdamanWithNullInit {
        private String innerState;

        public LambdamanWithNullInit(String innerState) {
            this.innerState = innerState;
        }

        String step(int counter) {
            return "na " + innerState;
        }


        /**
         * Method handle for {@link LambdamanWithNullInit#step(int)} not bound to any instance
         */
        private static MethodHandle stepHandle;

        static {
            try {
                stepHandle = MethodHandles.lookup().findVirtual(LambdamanWithNullInit.class, "step", MethodType.methodType(String.class, int.class));
            } catch (NoSuchMethodException | IllegalAccessException e) {
                CallUtils.fail("Unexpected exception: " + e.getMessage());
            }
        }

        /**
         * Creates method handle for {@link LambdamanWithNullInit#step(int)} bound to current instance
         */
        MethodHandle stepHandle() {
            return stepHandle.bindTo(this);
        }
    }


}

