import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

public class Main {
    interface Foo {
        public void bar();
    }
    enum MyEnum {
        A {
            public void bar() {
                System.out.println("Hello!");
            }
        },
        B,
        C;
    }
    public static void main(String[] arg) {
        try {
            patch();
        } catch(IOException|IllegalAccessException ex) {
            System.err.println("patching failed: "+ex);
            return;
        }
        test();
    }
    static void test() {
        for(MyEnum e: MyEnum.values()) {
            System.out.println(e.name());
            if (e instanceof Foo) {
                System.out.println("\timplements Foo");
                ((Foo)e).bar();
            }
        }
    }
    private static void patch() throws IOException, IllegalAccessException {
        ByteBuffer bb = ByteBuffer.wrap(Main.class
            .getResourceAsStream("Main$MyEnum$1.class").readAllBytes());
        int poolSize = bb.position(8).getChar();
        for(int ix = 1; ix < poolSize; ix++) {
            byte tag = bb.get();
            switch(tag) {
                default: bb.position(bb.position() + 4); break;
                case 1: bb.position(bb.getChar() + bb.position()); break;
                case 7: case 8: case 16: case 19: case 20:
                    bb.position(bb.position() + 2); break;
                case 5: case 6: bb.position(bb.position() + 8); ix++; break;
                case 15: bb.position(bb.position() + 3);
            }
        }
        ByteBuffer newBB = ByteBuffer.allocate(bb.capacity() + 16);
        newBB.put(bb.duplicate().flip());
        int ifType = poolSize;
        newBB.putShort(8, (short)(poolSize + 2));
        newBB.put((byte)7).putShort((short)(ifType + 1));
        byte[] ifName = "Main$Foo".getBytes(StandardCharsets.UTF_8);
        newBB.put((byte)1).putShort((short)ifName.length).put(ifName);
        bb.limit(bb.position() + 6);
        newBB.put(bb);
        bb.limit(bb.capacity());
        newBB.putShort((short)(bb.getShort() + 1)).putShort((short)ifType);
        newBB.put(bb);
        MethodHandles.lookup().defineClass(newBB.array());
    }
}