test :: (Throws ENotFound e, Throws ENotLoaded e, Throws UnexpectedEndMethod e, Throws (Located GeneratorError) e) => Generate e ()
test = do
  x <- newField [ACC_PUBLIC] "x" IntType
  -- Initializer method. Just calls java.lang.Object.<init>
  init <- newMethod [ACC_PUBLIC] "<init>" [] ReturnsVoid $ do
      setStackSize 4

      aload_ I0
      invokeSpecial Java.Lang.object Java.Lang.objectInit
      aload_ I0
      iconst_2
      putField "Test" x
      i0 RETURN

  testMethod <- newMethod [ACC_PUBLIC] "test" [] ReturnsVoid $ do
    setStackSize 20
    setMaxLocals 3

    generateJvm "Test" $ generate assignment

    getStaticField Java.Lang.system Java.IO.out
    loadString "Result: %d\n"
    iconst_1
    allocArray Java.Lang.object
    dup
    iconst_0
    iload_ I1
    invokeStatic Java.Lang.integer Java.Lang.valueOfInteger
    aastore
    invokeVirtual Java.IO.printStream Java.IO.printf

    i0 RETURN

  newMethod [ACC_PUBLIC, ACC_STATIC] "main" [arrayOf Java.Lang.stringClass] ReturnsVoid $ do
      setStackSize 3

      new "Test"
      dup
      invokeSpecial "Test" init
      invokeVirtual "Test" testMethod
      i0 RETURN

  return ()
test :: (Throws ENotFound e, Throws ENotLoaded e, Throws UnexpectedEndMethod e, Throws (Located GeneratorError) e) => Generate e ()
test = do
  x <- newField [ACC_PUBLIC] "x" IntType
  -- Initializer method. Just calls java.lang.Object.<init>
  init <- newMethod [ACC_PUBLIC] "<init>" [] ReturnsVoid $ do
      setStackSize 4

      aload_ I0
      invokeSpecial Java.Lang.object Java.Lang.objectInit
      aload_ I0
      iconst_2
      putField "Test" x
      i0 RETURN

  testMethod <- newMethod [ACC_PUBLIC] "test" [] ReturnsVoid $ do
    setStackSize 20
    setMaxLocals 3

    generateJvm "Test" $ generate assignment

    getStaticField Java.Lang.system Java.IO.out
    loadString "Result: %d\n"
    iconst_1
    allocArray Java.Lang.object
    dup
    iconst_0
    iload_ I1
    invokeStatic Java.Lang.integer Java.Lang.valueOfInteger
    aastore
    invokeVirtual Java.IO.printStream Java.IO.printf

    i0 RETURN

  newMethod [ACC_PUBLIC, ACC_STATIC] "main" [arrayOf Java.Lang.stringClass] ReturnsVoid $ do
      setStackSize 3

      new "Test"
      dup
      invokeSpecial "Test" init
      invokeVirtual "Test" testMethod
      i0 RETURN

  return ()
test = do
  x <- newField [ACC_PUBLIC] "x" IntType
  -- Initializer method. Just calls java.lang.Object.<init>
  init <- newMethod [ACC_PUBLIC] "<init>" [] ReturnsVoid $ do
      setStackSize 4

      aload_ I0
      invokeSpecial Java.Lang.object Java.Lang.objectInit
      aload_ I0
      iconst_2
      putField "Test" x
      i0 RETURN

  testMethod <- newMethod [ACC_PUBLIC] "test" [] ReturnsVoid $ do
    setStackSize 20
    setMaxLocals 3

    generateJvm "Test" $ generate assignment

    getStaticField Java.Lang.system Java.IO.out
    loadString "Result: %d\n"
    iconst_1
    allocArray Java.Lang.object
    dup
    iconst_0
    iload_ I1
    invokeStatic Java.Lang.integer Java.Lang.valueOfInteger
    aastore
    invokeVirtual Java.IO.printStream Java.IO.printf

    i0 RETURN

  newMethod [ACC_PUBLIC, ACC_STATIC] "main" [arrayOf Java.Lang.stringClass] ReturnsVoid $ do
      setStackSize 3

      new "Test"
      dup
      invokeSpecial "Test" init
      invokeVirtual "Test" testMethod
      i0 RETURN

  return ()