class TestCase::NativeAPI {
  use TestCase;
  use TestCase::Simple;
  use TestCase::Minimal;
  use TestCase::Pointer;
  use TestCase::Callback::Callback;
  use TestCase::Callback::ImplementCallback1;
  use TestCase::Callback::ImplementCallback2;
  use Fn;
  
  our $BYTE_VALUE : byte;
  our $SHORT_VALUE : short;
  our $INT_VALUE : int;
  our $LONG_VALUE : long;
  our $FLOAT_VALUE : float;
  our $DOUBLE_VALUE : double;
  our $MINIMAL_VALUE : TestCase::Minimal;
  
  static method new : TestCase::NativeAPI () {
    return new TestCase::NativeAPI;
  }

  native static method check_native_api_indexes : int ();
  native static method check_native_api_precompile_indexes : int ();
  native static method check_native_api_string_buffer_indexes : int ();
  native static method check_native_api_allocator_indexes : int ();
  native static method check_native_api_compiler_indexes : int ();
  native static method check_native_api_runtime_indexes : int ();
  native static method check_native_api_constant_values : int ();

  static method get_class_var_byte_by_name : int () {

    $BYTE_VALUE = Fn->INT8_MIN();
    
    my $value = TestCase::NativeAPI->get_class_var_byte_by_name_test();
    
    unless ($value == Fn->INT8_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method get_class_var_byte_by_name_test : byte ();
  
  static method get_class_var_byte_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->get_class_var_byte_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_byte_by_name_test_exception : byte ();

  static method get_class_var_short_by_name : int () {

    $SHORT_VALUE = Fn->INT16_MIN();
    
    my $value = TestCase::NativeAPI->get_class_var_short_by_name_test();
    
    unless ($value == Fn->INT16_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method get_class_var_short_by_name_test : short ();
  
  static method get_class_var_short_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->get_class_var_short_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_short_by_name_test_exception : short ();

  static method get_class_var_int_by_name : int () {

    $INT_VALUE = Fn->INT32_MIN();
    
    my $value = TestCase::NativeAPI->get_class_var_int_by_name_test();
    
    unless ($value == Fn->INT32_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method get_class_var_int_by_name_test : int ();
  
  static method get_class_var_int_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->get_class_var_int_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_int_by_name_test_exception : int ();

  static method get_class_var_long_by_name : long () {

    $LONG_VALUE = Fn->INT64_MIN();
    
    my $value = TestCase::NativeAPI->get_class_var_long_by_name_test();
    
    unless ($value == Fn->INT64_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method get_class_var_long_by_name_test : long ();
  
  static method get_class_var_long_by_name_exception : long () {
    
    eval { TestCase::NativeAPI->get_class_var_long_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_long_by_name_test_exception : long ();

  static method get_class_var_float_by_name : int () {

    $FLOAT_VALUE = Fn->FLT_MIN();
    
    my $value = TestCase::NativeAPI->get_class_var_float_by_name_test();
    
    unless ($value == Fn->FLT_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method get_class_var_float_by_name_test : float ();
  
  static method get_class_var_float_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->get_class_var_float_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_float_by_name_test_exception : float ();

  static method get_class_var_double_by_name : int () {

    $DOUBLE_VALUE = Fn->DBL_MIN();
    
    my $value = TestCase::NativeAPI->get_class_var_double_by_name_test();
    
    unless ($value == Fn->DBL_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method get_class_var_double_by_name_test : double ();
  
  static method get_class_var_double_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->get_class_var_double_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_double_by_name_test_exception : double ();

  static method get_class_var_object_by_name : int () {
    
    $MINIMAL_VALUE = TestCase::Minimal->new;
    
    my $value = TestCase::NativeAPI->get_class_var_object_test();
    
    unless ($value isa TestCase::Minimal) {
      $MINIMAL_VALUE = undef;
      return 0;
    }
    
    $MINIMAL_VALUE = undef;
    
    return 1;
  }
  native static method get_class_var_object_test : TestCase::Minimal ();

  static method get_class_var_object_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->get_class_var_object_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method get_class_var_object_by_name_test_exception : object ();
  
  static method set_class_var_byte_by_name : int () {
    
    TestCase::NativeAPI->set_class_var_byte_by_name_test();
    
    if ($BYTE_VALUE == Fn->INT8_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_byte_by_name_test : void ();

  static method set_class_var_byte_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_byte_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_byte_by_name_test_exception : byte ();

  static method set_class_var_short_by_name : int () {
    
    TestCase::NativeAPI->set_class_var_short_by_name_test();
    
    if ($SHORT_VALUE == Fn->INT16_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_short_by_name_test : void ();

  static method set_class_var_short_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_short_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_short_by_name_test_exception : short ();

  static method set_class_var_int_by_name : int () {
    
    TestCase::NativeAPI->set_class_var_int_by_name_test();
    
    if ($INT_VALUE == Fn->INT32_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_int_by_name_test : void ();

  static method set_class_var_int_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_int_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_int_by_name_test_exception : int ();

  static method set_class_var_long_by_name : int () {
    
    TestCase::NativeAPI->set_class_var_long_by_name_test();
    
    if ($LONG_VALUE == Fn->INT64_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_long_by_name_test : void ();

  static method set_class_var_long_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_long_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_long_by_name_test_exception : long ();

  static method set_class_var_float_by_name : int () {
    TestCase::NativeAPI->set_class_var_float_by_name_test();
    
    if ($FLOAT_VALUE == Fn->FLT_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_float_by_name_test : void ();

  static method set_class_var_float_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_float_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_float_by_name_test_exception : float ();

  static method set_class_var_double_by_name : int () {
    TestCase::NativeAPI->set_class_var_double_by_name_test();
    
    if ($DOUBLE_VALUE == Fn->DBL_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_double_by_name_test : void ();

  static method set_class_var_double_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_double_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_double_by_name_test_exception : double ();

  static method set_class_var_object_by_name : int () {
    
    TestCase::NativeAPI->set_class_var_object_by_name_test();
    
    if ($MINIMAL_VALUE isa TestCase::Minimal) {
      $MINIMAL_VALUE = undef;
      return 1;
    }
    
    return 0;
  }
  native static method set_class_var_object_by_name_test : void ();

  static method set_class_var_object_by_name_exception : int () {
    
    eval { TestCase::NativeAPI->set_class_var_object_by_name_test_exception(); };
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method set_class_var_object_by_name_test_exception : object ();

  native static method has_interface_test : int ($object : object);
  static method has_interface : int () {
    my $impl1 = TestCase::Callback::ImplementCallback1->new;
    my $impl1s = new TestCase::Callback::ImplementCallback1[3];
    my $minimal = TestCase::Minimal->new;

    unless (TestCase::NativeAPI->has_interface_test($impl1)) {
      return 0;
    }
    
    unless (!TestCase::NativeAPI->has_interface_test($impl1s)) {
      return 0;
    }
    
    unless (!TestCase::NativeAPI->has_interface_test($minimal)) {
      return 0;
    }
    
    return 1;
  }

  native static method is_type_test_minimals : int ($object : object);
  static method is_type : int () {
    my $minimals = new TestCase::Minimal[3];
    my $minimal = TestCase::Minimal->new;
    my $simples = new TestCase::Simple[3];

    unless (TestCase::NativeAPI->is_type_test_minimals($minimals)) {
      return 0;
    }
    
    unless (!TestCase::NativeAPI->is_type_test_minimals($minimal)) {
      return 0;
    }
    
    unless (!TestCase::NativeAPI->is_type_test_minimals($simples)) {
      return 0;
    }
    
    return 1;
  }

  native static method ref_byte_sum : byte ($x_in : byte, $x_in2 : byte, $x_out : byte*);
  static method ref_byte : int () {
    my $out : byte;
    my $out_ref = \$out;
    
    TestCase::NativeAPI->ref_byte_sum(1, Fn->INT8_MIN(), $out_ref);
    
    if ($$out_ref == Fn->INT8_MIN() + 1) {
      return 1;
    }
    
    return 0;
  }

  native static method ref_short_sum : short ($x_in : short, $x_in2 : short, $x_out : short*);
  static method ref_short : int () {
    my $out : short;
    my $out_ref = \$out;
    
    TestCase::NativeAPI->ref_short_sum(1, Fn->INT16_MIN(), $out_ref);
    
    if ($$out_ref == Fn->INT16_MIN() + 1) {
      return 1;
    }
    
    return 0;
  }

  native static method ref_int_sum : int ($x_in : int, $x_in2 : int, $x_out : int*);
  static method ref_int : int () {
    my $out : int;
    my $out_ref = \$out;
    
    TestCase::NativeAPI->ref_int_sum(1, Fn->INT32_MIN(), $out_ref);
    
    if ($$out_ref == Fn->INT32_MIN() + 1) {
      return 1;
    }
    
    return 0;
  }

  native static method ref_long_sum : long ($x_in : long, $x_in2 : long, $x_out : long*);
  static method ref_long : int () {
    my $out : long;
    my $out_ref = \$out;
    
    TestCase::NativeAPI->ref_long_sum(1, Fn->INT64_MIN(), $out_ref);
    
    if ($$out_ref == Fn->INT64_MIN() + 1) {
      return 1;
    }
    
    return 0;
  }
  
  native static method ref_float_sum : float ($x_in : float, $x_in2 : float, $x_out : float*);
  static method ref_float : int () {
    my $out : float;
    my $out_ref = \$out;
    
    TestCase::NativeAPI->ref_float_sum(0.25f, Fn->FLT_MIN(), $out_ref);
    
    if ($$out_ref == Fn->FLT_MIN() + 0.25f) {
      return 1;
    }
    
    return 0;
  }

  native static method ref_double_sum : double ($x_in : double, $x_in2 : double, $x_out : double*);
  static method ref_double : int () {
    my $out : double;
    my $out_ref = \$out;
    
    TestCase::NativeAPI->ref_double_sum(0.25, Fn->DBL_MIN(), $out_ref);
    
    if ($$out_ref == Fn->DBL_MIN() + 0.25) {
      return 1;
    }
    
    return 0;
  }

  static method set_field_byte_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_byte_by_name($simple);
    
    unless ($simple->{byte_value} == Fn->INT8_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method native_set_field_byte_by_name : void ($simple : TestCase::Simple);

  static method set_field_byte_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_byte_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }
    
    $@ = 0;
    
    return 1;
  }
  native static method native_set_field_byte_by_name_exception : void ($simple : TestCase::Simple);

  static method set_field_short_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_short_by_name($simple);
    
    if ($simple->{short_value} == Fn->INT16_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method native_set_field_short_by_name : void ($simple : TestCase::Simple);

  static method set_field_short_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_short_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_set_field_short_by_name_exception : void ($simple : TestCase::Simple);

  static method set_field_int_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_int_by_name($simple);
    
    unless ($simple->{int_value} == Fn->INT32_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method native_set_field_int_by_name : void ($simple : TestCase::Simple);

  static method set_field_int_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_int_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_set_field_int_by_name_exception : void ($simple : TestCase::Simple);

  static method set_field_long_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_long_by_name($simple);
    
    if ($simple->{long_value} == Fn->INT64_MIN()) {
      return 1;
    }
    
    return 0;
  }
  native static method native_set_field_long_by_name : void ($simple : TestCase::Simple);

  static method set_field_long_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_long_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_set_field_long_by_name_exception : void ($simple : TestCase::Simple);

  static method set_field_float_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_float_by_name($simple);
    
    unless ($simple->{float_value} == Fn->FLT_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method native_set_field_float_by_name : void ($simple : TestCase::Simple);

  static method set_field_float_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_float_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }

    $@ = undef;
    
    return 1;
  }
  native static method native_set_field_float_by_name_exception : void ($simple : TestCase::Simple);

  static method set_field_double_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_double_by_name($simple);
    
    unless ($simple->{double_value} == Fn->DBL_MIN()) {
      return 0;
    }
    
    return 1;
  }
  native static method native_set_field_double_by_name : void ($simple : TestCase::Simple);

  static method set_field_double_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_double_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }
    
    return 1;
  }
  native static method native_set_field_double_by_name_exception : void ($simple : TestCase::Simple);

  static method set_field_object_by_name : int () {
    my $simple = TestCase::Simple->new;
    
    TestCase::NativeAPI->native_set_field_object_by_name($simple);
    
    unless ($simple->{object_value}{x} == 3) {
      return 0;
    }
    
    return 1;
  }
  native static method native_set_field_object_by_name : int ($simple : TestCase::Simple);

  static method set_field_object_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    
    eval { TestCase::NativeAPI->native_set_field_object_by_name_exception($simple); };
    
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method native_set_field_object_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_byte_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{byte_value} = Fn->INT8_MIN();
    
    my $success = TestCase::NativeAPI->native_get_field_byte_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_byte_by_name : int ($simple : TestCase::Simple);

  static method get_field_byte_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{byte_value} = Fn->INT8_MIN();
    
    eval { TestCase::NativeAPI->native_get_field_byte_by_name_exception($simple); };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_get_field_byte_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_short_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{short_value} = Fn->INT16_MIN();
    
    my $success = TestCase::NativeAPI->native_get_field_short_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_short_by_name : int ($simple : TestCase::Simple);

  static method get_field_short_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{short_value} = Fn->INT16_MIN();
    
    eval { TestCase::NativeAPI->native_get_field_short_by_name_exception($simple); };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_get_field_short_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_int_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{int_value} = Fn->INT32_MIN();
    
    my $success = TestCase::NativeAPI->native_get_field_int_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_int_by_name : int ($simple : TestCase::Simple);

  static method get_field_int_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{int_value} = Fn->INT32_MIN();
    
    eval { TestCase::NativeAPI->native_get_field_int_by_name_exception($simple); };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_get_field_int_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_long_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{long_value} = Fn->INT64_MIN();
    
    my $success = TestCase::NativeAPI->native_get_field_long_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_long_by_name : int ($simple : TestCase::Simple);

  static method get_field_long_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{long_value} = Fn->INT64_MIN();
    
    eval { TestCase::NativeAPI->native_get_field_long_by_name_exception($simple) ; };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_get_field_long_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_float_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{float_value} = Fn->FLT_MIN();
    
    my $success = TestCase::NativeAPI->native_get_field_float_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_float_by_name : int ($simple : TestCase::Simple);

  static method get_field_float_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{float_value} = Fn->FLT_MIN();
    
    eval { TestCase::NativeAPI->native_get_field_float_by_name_exception($simple); };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_get_field_float_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_double_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{double_value} = Fn->DBL_MIN();
    
    my $success = TestCase::NativeAPI->native_get_field_double_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_double_by_name : int ($simple : TestCase::Simple);

  static method get_field_double_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{double_value} = Fn->DBL_MIN();
    
    eval { TestCase::NativeAPI->native_get_field_double_by_name_exception($simple); };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    
    return 1;
  }
  native static method native_get_field_double_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_object_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{object_value} = TestCase::Minimal->new;
    $simple->{object_value}{x} = 5;
    
    my $success = TestCase::NativeAPI->native_get_field_object_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_object_by_name : int ($simple : TestCase::Simple);

  static method get_field_object_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{object_value} = TestCase::Minimal->new;
    $simple->{object_value}{x} = 5;
    
    eval { TestCase::NativeAPI->native_get_field_object_by_name_exception($simple); };
    unless ($@) {
      return 0;
    }
    
    return 1;
  }
  native static method native_get_field_object_by_name_exception : int ($simple : TestCase::Simple);

  static method get_field_string_chars_by_name : int () {
    my $simple = TestCase::Simple->new;
    $simple->{string_value} = "abc";
    
    my $success = TestCase::NativeAPI->native_get_field_string_chars_by_name($simple);
    
    return $success;
  }
  native static method native_get_field_string_chars_by_name : int ($simple : TestCase::Simple);

  static method get_field_string_chars_by_name_exception : int () {
    my $simple = TestCase::Simple->new;
    $simple->{string_value} = "abc";
    
    my $success = TestCase::NativeAPI->native_get_field_string_chars_by_name_exception($simple);
    
    return $success;
  }
  native static method native_get_field_string_chars_by_name_exception : int ($simple : TestCase::Simple);

  static method spvm_extension_add_int_array : int () {
    my $nums1 = [1, 2, 3];
    my $nums2 = [4, 5, 6];
    
    my $nums3 = TestCase::NativeAPI->add_int_array($nums1, $nums2);
    
    if ($nums3->[0] == 5) {
      if ($nums3->[1] == 7) {
        if ($nums3->[2] == 9) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  static method spvm_extension : int () {
    my $total = TestCase::NativeAPI->sum(2, 3);
    
    if ($total == 5) {
      return 1;
    }
    
    return 0;
  }
  
  static method native_use_strlen_test : int () {
    my $string = "abcde";
    my $length = TestCase::NativeAPI->native_use_strlen($string);
    if ($length == 5) {
      return 1;
    }
    
    return 0;
  }

  native static method native_use_strlen : int ($string : string);

  native static method native_env_get_field_byte : byte ($test_case : TestCase);
  native static method native_env_get_field_short : short ($test_case : TestCase);
  native static method native_env_get_field_int : int ($test_case : TestCase);
  native static method native_env_get_field_long : long ($test_case : TestCase);
  native static method native_env_get_field_float : float ($test_case : TestCase);
  native static method native_env_get_field_double : double ($test_case : TestCase);
  native static method native_env_get_field_object : TestCase::Minimal ($test_case : TestCase);
  
  static method native_env_set_field : int () {
    
    my $test_case = TestCase->new();
    
    $test_case->{x_byte} = (byte)1;
    $test_case->{x_short} = (short)2;
    $test_case->{x_int} = 3;
    $test_case->{x_long} = 4L;
    $test_case->{x_float} = 0.5f;
    $test_case->{x_double} = 0.025;
    my $minimal1 = TestCase::Minimal->new();
    $test_case->{minimal} = $minimal1;
    
    my $x_byte1 = TestCase::NativeAPI->native_env_get_field_byte($test_case);
    my $x_short1 = TestCase::NativeAPI->native_env_get_field_short($test_case);
    my $x_int1 = TestCase::NativeAPI->native_env_get_field_int($test_case);
    my $x_long1 = TestCase::NativeAPI->native_env_get_field_long($test_case);
    my $x_float1 = TestCase::NativeAPI->native_env_get_field_float($test_case);
    my $x_double1 = TestCase::NativeAPI->native_env_get_field_double($test_case);
    my $minimal2 = TestCase::NativeAPI->native_env_get_field_object($test_case);
    
    if ((int)$x_byte1 == (int)(byte)1) {
      if ((int)$x_short1 == (int)(short)2) {
        if ($x_int1 == 3) {
          if ($x_long1 == 4L) {
            if ($x_float1 == 0.5f) {
              if ($x_double1 == 0.025) {
                if ($minimal1 == $minimal2) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
  }

  native static method sum : int ($num1 : int, $num2 : int);
  
  native static method add_int_array : int[] ($nums1 : int[], $nums2 : int[]);

  static method call_void_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_void_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  static method call_byte_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_byte_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  static method call_short_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_short_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  static method call_int_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_int_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  static method call_long_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_long_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  static method call_float_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_float_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  static method call_double_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_double_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }
  
  static method call_object_method_exception : int () {
    eval {
      TestCase::NativeAPI->call_object_method_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }
  
  native static method call_void_method_exception_native : void ();
  native static method call_byte_method_exception_native : byte ();
  native static method call_short_method_exception_native : short ();
  native static method call_int_method_exception_native : int ();
  native static method call_long_method_exception_native : long ();
  native static method call_float_method_exception_native : float ();
  native static method call_double_method_exception_native : double ();
  native static method call_object_method_exception_native : double ();
  
  native static method mortal_api : int ();
  native static method enter_scope_leave_scope : int ();
  native static method push_mortal_multi : int ();
  
  static method my_value : int ($value : int) { return $value; }
  
  native static method native_call_spvm_method : int ();
  native static method native_call_class_method_by_name : int ();
  native static method native_call_class_method_by_name_exception : int ();

  static method call_instance_method_by_name : int () {
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x(5);
    
    my $value = &call_instance_method_by_name_native($minimal);
    
    unless ($value == 5) {
      return 0;
    }
    
    return 1;
  }
  native static method call_instance_method_by_name_native : int ($minimal : TestCase::Minimal);
  static method call_instance_method_by_name_exception : int () {
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x(5);

    &call_instance_method_by_name_exception_native($minimal);
    
    return 1;
  }
  native static method call_instance_method_by_name_exception_native : int ($minimal : TestCase::Minimal);

  native static method native_call_class_method : int ();
  native static method native_call_instance_method : int ();

  static method new_object_by_name : int () {
    my $minimal = TestCase::NativeAPI->native_new_object_by_name();
    unless ($minimal isa TestCase::Minimal) {
      return 0;
    }
    
    unless ($minimal isa TestCase::Minimal) {
      return 0;
    }
    
    return 1;
  }
  native static method native_new_object_by_name : TestCase::Minimal ();

  static method new_object_by_name_exception : int () {
    my $minimal : TestCase::Minimal;
    eval { $minimal = TestCase::NativeAPI->native_new_object_by_name_exception(); };
    
    unless ($@) {
      return 0;
    }
    
    if ($minimal) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method native_new_object_by_name_exception : TestCase::Minimal ();


  
  static method new_pointer_by_name : int () {
    my $pointer = TestCase::Pointer->new(3);
    
    unless ($pointer isa TestCase::Pointer) {
      return 0;
    }
    
    unless ($pointer->get_x == 3) {
      return 0;
    }
    
    return 1;
  }

  static method new_pointer_by_name_exception : int () {
    my $pointer : TestCase::Pointer;
    eval { $pointer = TestCase::NativeAPI->native_new_pointer_by_name_exception(); };
    
    unless ($@) {
      return 0;
    }
    
    $@ = undef;
    return 1;
  }
  native static method native_new_pointer_by_name_exception : TestCase::Pointer ();

  static method get_instance_method_id_static : int () {
    
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x(4);
    
    my $x = &get_instance_method_id_static_native($minimal);
    unless ($x == 4) {
      return 0;
    }
    
    return 1;
  }
  native static method get_instance_method_id_static_native : int ($minimal : TestCase::Minimal);
  
  static method get_bool_object_value : int () {
    
    # true
    {
      my $true = true;
      my $value = &get_bool_object_value_native($true);
      unless ($value == 1) {
        return 0;
      }
    }
    
    # false
    {
      my $false = false;
      my $value = &get_bool_object_value_native($false);
      unless ($value == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  native static method get_bool_object_value_native : int ($bool_object : Bool);

  native static method new_string_raw : int ();

  native static method new_string : int ();

  native static method new_string_nolen_raw : int ();

  native static method new_string_nolen : int ();
  
}