class TestCase::ExchangeAPI {
  use TestCase::Point_3b;
  use TestCase::Point_3s;
  use TestCase::Point_3i;
  use TestCase::Point_3l;
  use TestCase::Point_3f;
  use TestCase::Point_3d;
  use TestCase::Minimal;
  use Complex_2d;
  use Fn;
  
  static method FLOAT_PRECICE : float () { return 16384.5f; }
  static method DOUBLE_PRECICE : double () { return 65536.5; }
  use Fn;

  static method return_object : TestCase::Minimal () {
    
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x(1);
    $minimal->set_y(2);
    
    return $minimal;
  }

  static method return_object_undef : TestCase::Minimal () {
    
    return undef;
  }

  static method return_any_object : object () {
    
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x(1);
    $minimal->set_y(2);
    
    return $minimal;
  }

  static method return_any_object_undef : object () {
    
    return undef;
  }

  static method return_void : void () {
    
    return;
  }

  static method return_string : string () {
    
    return "あいう";
  }

  static method return_string_undef : string () {
    
    return undef;
  }

  static method return_numeric_array : int[] () {
    
    my $nums = [1, 2, 3];

    return $nums;
  }

  static method return_numeric_array_undef : int[] () {
    
    return undef;
  }

  static method return_object_array : TestCase::Minimal[] () {
    
    my $minimal = new TestCase::Minimal[2];
    $minimal->[0] = new TestCase::Minimal;
    $minimal->[0]->set_x(1);
    $minimal->[0]->set_y(2);
    $minimal->[1] = new TestCase::Minimal;
    $minimal->[1]->set_x(3);
    $minimal->[1]->set_y(4);
    
    return $minimal;
  }

  static method return_object_array_undef : TestCase::Minimal[] () {
    
    return undef;
  }

  static method return_any_object_array : object[] () {
    
    my $minimal = new TestCase::Minimal[2];
    $minimal->[0] = new TestCase::Minimal;
    $minimal->[0]->set_x(1);
    $minimal->[0]->set_y(2);
    $minimal->[1] = new TestCase::Minimal;
    $minimal->[1]->set_x(3);
    $minimal->[1]->set_y(4);
    
    return $minimal;
  }

  static method return_any_object_array_undef : TestCase::Minimal[] () {
    
    return undef;
  }

  static method return_multi_numeric_array : TestCase::Point_3i[] () {
    
    my $nums = new TestCase::Point_3i[2];
    $nums->[0]{x} = 1;
    $nums->[1]{z} = 5;

    return $nums;
  }

  static method return_multi_numeric_array_undef : TestCase::Point_3i[] () {
    
    return undef;
  }

  static method return_byte_multi_numeric : TestCase::Point_3b () {
    my $point : TestCase::Point_3b;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = Fn->INT8_MIN();
    
    return $point;
  }
  
  static method return_short_multi_numeric : TestCase::Point_3s () {
    my $point : TestCase::Point_3s;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = Fn->INT16_MIN();
    
    return $point;
  }

  static method return_int_multi_numeric : TestCase::Point_3i () {
    my $point : TestCase::Point_3i;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = Fn->INT32_MIN();
    
    return $point;
  }

  static method return_long_multi_numeric : TestCase::Point_3l () {
    my $point : TestCase::Point_3l;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = Fn->INT64_MIN();
    
    return $point;
  }

  static method return_float_multi_numeric : TestCase::Point_3f () {
    my $point : TestCase::Point_3f;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = Fn->FLT_MIN();
    
    return $point;
  }

  static method return_double_multi_numeric : TestCase::Point_3d () {
    my $point : TestCase::Point_3d;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = Fn->DBL_MIN();
    
    return $point;
  }

  static method return_byte : byte () {
    
    return Fn->INT8_MIN();
  }
  
  static method return_short : short () {
    
    return Fn->INT16_MIN();
  }

  static method return_int : int () {
    
    return Fn->INT32_MIN();
  }

  static method return_long : long () {
    
    return Fn->INT64_MIN();
  }

  static method return_float : float () {
    
    return Fn->FLT_MIN();
  }

  static method return_double : double () {
    
    return Fn->DBL_MIN();
  }

  static method set_exception : int () {
    my $exception = $@;
    
    unless ($exception eq "あいう") {
      return 0;
    }
    
    return 1;
  }

  static method set_exception_undef : int () {
    my $exception = $@;
    
    unless ($exception == undef) {
      return 0;
    }
    
    return 1;
  }
  
  static method any_object_array : object[] ($any_object_array : object[]) {
    
    my $bytes = (Byte[])$any_object_array;
    
    $bytes->[2] = Byte->new(5);
    
    return $bytes;
  }
  
  static method argument_non_ref_scalar_to_string_ascii : int ($string : string) {
    
    unless ($string eq "ABC") {
      return 0;
    }
    
    return 1;
  }
  
  static method argument_non_ref_scalar_to_string_decoded_string : int ($string : string) {
    
    unless ($string eq "あいう") {
      return 0;
    }
    
    return 1;
  }
  
  static method argument_non_ref_scalar_to_string_number : int ($string : string) {
    
    unless ($string eq "4.12") {
      return 0;
    }
    
    return 1;
  }

  static method argument_non_ref_scalar_to_string_undef : int ($string : string) {
    
    unless ($string == undef) {
      return 0;
    }
    
    return 1;
  }


  static method argument_blessed_object_string_to_string : int ($string : string) {
    
    unless ($string eq "あいう") {
      return 0;
    }
    
    return 1;
  }

  static method argument_blessed_object_string_to_string_undef : int ($string : string) {
    
    unless ($string == undef) {
      return 0;
    }
    
    return 1;
  }
  
  static method call_spvm_method_multi_numeric_arg_byte : TestCase::Point_3b ($point : TestCase::Point_3b) {
    return $point;
  }

  static method call_spvm_method_multi_numeric_arg_short : TestCase::Point_3s ($point : TestCase::Point_3s) {
    return $point;
  }

  static method call_spvm_method_multi_numeric_arg_int : TestCase::Point_3i ($point : TestCase::Point_3i) {
    return $point;
  }

  static method call_spvm_method_multi_numeric_arg_long : TestCase::Point_3l ($point : TestCase::Point_3l) {
    return $point;
  }

  static method call_spvm_method_multi_numeric_arg_float : TestCase::Point_3f ($point : TestCase::Point_3f) {
    return $point;
  }

  static method call_spvm_method_multi_numeric_arg_double : TestCase::Point_3d ($point : TestCase::Point_3d) {
    return $point;
  }
  
  static method call_spvm_method_multi_numeric_ref_numeric_ref_mixed_arg : void ($point1 : TestCase::Point_3i*, $value1 : int*, $point2 : TestCase::Point_3i*, $value2 : int*) {
    $point1->{x} = (int)($point1->{x} + 1);
    $point1->{y} = (int)($point1->{y} + 1);
    $point1->{z} = (int)($point1->{z} + 1);

    $$value1 = $$value1 + 1;

    $point2->{x} = (int)($point2->{x} + 1);
    $point2->{y} = (int)($point2->{y} + 1);
    $point2->{z} = (int)($point2->{z} + 1);

    $$value2 = $$value2 + 1;
  }

  static method call_spvm_method_multi_numeric_ref_arg_byte : int ($point : TestCase::Point_3b*) {
    $point->{x} = (byte)($point->{x} + 1);
    $point->{y} = (byte)($point->{y} + 1);
    $point->{z} = (byte)($point->{z} + 1);
  }

  static method call_spvm_method_multi_numeric_ref_arg_short : int ($point : TestCase::Point_3s*) {
    $point->{x} = (short)($point->{x} + 1);
    $point->{y} = (short)($point->{y} + 1);
    $point->{z} = (short)($point->{z} + 1);
  }

  static method call_spvm_method_multi_numeric_ref_arg_int : int ($point : TestCase::Point_3i*) {
    $point->{x} = (int)($point->{x} + 1);
    $point->{y} = (int)($point->{y} + 1);
    $point->{z} = (int)($point->{z} + 1);
  }

  static method call_spvm_method_multi_numeric_ref_arg_long : int ($point : TestCase::Point_3l*) {
    $point->{x} = (long)($point->{x} + 1);
    $point->{y} = (long)($point->{y} + 1);
    $point->{z} = (long)($point->{z} + 1);
  }

  static method call_spvm_method_multi_numeric_ref_arg_float : int ($point : TestCase::Point_3f*) {
    $point->{x} = (float)($point->{x} + 1);
    $point->{y} = (float)($point->{y} + 1);
    $point->{z} = (float)($point->{z} + 1);
  }

  static method call_spvm_method_multi_numeric_ref_arg_double : int ($point : TestCase::Point_3d*) {
    $point->{x} = (double)($point->{x} + 1);
    $point->{y} = (double)($point->{y} + 1);
    $point->{z} = (double)($point->{z} + 1);
  }
  
  static method call_spvm_method_numeric_ref_arg_byte : int ($byte_val : byte*) {
    $$byte_val = (byte)($$byte_val + 1);
  }
  
  static method call_spvm_method_numeric_ref_arg_short : int ($short_val : short*) {
    $$short_val = (short)($$short_val + 1);
  }
  
  static method call_spvm_method_numeric_ref_arg_int : int ($int_val : int*) {
    $$int_val = $$int_val + 1;
  }

  static method call_spvm_method_numeric_ref_arg_long : int ($long_val : long*) {
    $$long_val = $$long_val + 1;
  }

  static method call_spvm_method_numeric_ref_arg_float : int ($float_val : float*) {
    $$float_val = $$float_val + 1;
  }

  static method call_spvm_method_numeric_ref_arg_double : int ($double_val : double*) {
    $$double_val = $$double_val + 1;
  }
  
  static method spvm_object_set_object : int ($obj : TestCase) {
    my $nums = $obj->{x_int_array};
    my $values = ($obj->{x_byte_array});
    
    
    # [INT32_MAX, INT32_MAX]
    if (@$nums == 2) {
      if ($nums->[0] == 2147483647) {
        if ($nums->[1] == 2147483647) {
          # abc
          if ($values->[0] == 97) {
            if ($values->[1] == 98) {
              if ($values->[2] == 99) {
                if (@$values == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_object_set : int ($obj : TestCase) {
    if ($obj->{x_byte} == 127) {
      if ($obj->{x_short} == 32767) {
        if ($obj->{x_int} == 2147483647) {
          if ($obj->{x_long} == 9223372036854775807L) {
            if ($obj->{x_float} == TestCase::ExchangeAPI->FLOAT_PRECICE()) {
              if ($obj->{x_double} == TestCase::ExchangeAPI->DOUBLE_PRECICE()) {
                if ($obj->{minimal}->{x} == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method return_byte_object_only : Byte ($values : Byte) {
    
    return $values;
  }

  static method return_short_object_only : Short ($values : Short) {
    
    return $values;
  }

  static method return_int_object_only : Int ($values : Int) {
    
    return $values;
  }

  static method return_long_object_only : Long ($values : Long) {
    
    return $values;
  }

  static method return_float_object_only : Float ($values : Float) {
    
    return $values;
  }

  static method return_double_object_only : Double ($values : Double) {
    
    return $values;
  }
  
  static method return_any_object_only : object ($values : object) {
    
    return $values;
  }

  static method argument_perl_array_ref_to_spvm_string_array : int ($values : string[], $undef : string[]) {
    
    unless (@$values == 4) {
      return 0;
    }
    
    unless ($values->[0] eq "あいう") {
      return 0;
    }
    
    unless ($values->[1] eq "えお") {
      return 0;
    }
    
    unless ($values->[2] eq "ab") {
      return 0;
    }

    unless ($values->[3] == undef) {
      return 0;
    }
    
    unless ($undef == undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_string_array_to_spvm_string_array : int ($values : string[], $undef : string[]) {
    
    unless (@$values == 4) {
      return 0;
    }
    
    unless ($values->[0] eq "あいう") {
      return 0;
    }
    
    unless ($values->[1] eq "えお") {
      return 0;
    }
    
    unless ($values->[2] eq "ab") {
      return 0;
    }

    unless ($values->[3] == undef) {
      return 0;
    }
    
    unless ($undef == undef) {
      return 0;
    }
    
    return 1;
  }
  
  static method argument_perl_array_ref_to_spvm_byte_array : int ($values : byte[], $undef : byte[]) {
    
    unless (Fn->equals_array_byte($values, [(byte)1, Fn->INT8_MAX(), Fn->INT8_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_perl_array_ref_to_spvm_short_array : int ($values : short[], $undef : short[]) {
    
    unless (Fn->equals_array_short($values, [(short)1, Fn->INT16_MAX(), Fn->INT16_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_perl_array_ref_to_spvm_int_array : int ($values : int[], $undef : int[]) {
    
    unless (Fn->equals_array_int($values, [(int)1, Fn->INT32_MAX(), Fn->INT32_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_perl_array_ref_to_spvm_long_array : int ($values : long[], $undef : long[]) {
    
    unless (Fn->equals_array_long($values, [(long)1, Fn->INT64_MAX(), Fn->INT64_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_perl_array_ref_to_spvm_float_array : int ($values : float[], $undef : float[]) {
    
    unless (Fn->equals_array_float($values, [(float)0.5, Fn->FLT_MAX(), Fn->FLT_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_perl_array_ref_to_spvm_double_array : int ($values : double[], $undef : double[]) {
    
    unless (Fn->equals_array_double($values, [(double)0.5, Fn->DBL_MAX(), Fn->DBL_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_array_to_spvm_byte_array : int ($values : byte[], $undef : byte[]) {
    
    unless (Fn->equals_array_byte($values, [(byte)1, Fn->INT8_MAX(), Fn->INT8_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_array_to_spvm_short_array : int ($values : short[], $undef : short[]) {
    
    unless (Fn->equals_array_short($values, [(short)1, Fn->INT16_MAX(), Fn->INT16_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_array_to_spvm_int_array : int ($values : int[], $undef : int[]) {
    
    unless (Fn->equals_array_int($values, [(int)1, Fn->INT32_MAX(), Fn->INT32_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_array_to_spvm_long_array : int ($values : long[], $undef : long[]) {
    
    unless (Fn->equals_array_long($values, [(long)1, Fn->INT64_MAX(), Fn->INT64_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_array_to_spvm_float_array : int ($values : float[], $undef : float[]) {
    
    unless (Fn->equals_array_float($values, [(float)0.5, Fn->FLT_MAX(), Fn->FLT_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  static method argument_spvm_array_to_spvm_double_array : int ($values : double[], $undef : double[]) {
    
    unless (Fn->equals_array_double($values, [(double)0.5, Fn->DBL_MAX(), Fn->DBL_MIN()])) {
      return 0;
    }
    
    if ($undef) {
      return 0;
    }
    
    return 1;
  }

  # SPVM Functions
  static method spvm_new_byte_array_from_bin : int ($values : byte[]) {
    
    unless ((string)$values eq "あ") {
      return 0;
    }
    
    return 1;
  }

  static method spvm_new_byte_array_bin : int ($values : byte[]) {
    
    if ($values->[0] == 97) {
      if ($values->[1] == 98) {
        if ($values->[2] == 99) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  static method new_byte_array_from_string : int ($bytes : byte[]) {
    
    unless ($bytes isa byte[]) {
      return 0;
    }
    
    unless ((string)$bytes eq "あいう") {
      return 0;
    }
    
    return 1;
  }

  static method spvm_new_byte_array_binary_pack : int ($values : byte[]) {
    
    if ($values->[0] == 97) {
      if ($values->[1] == 98) {
        if ($values->[2] == Fn->INT8_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_short_array_binary_pack : int ($values : short[]) {
    
    if ((int)$values->[0] == (int)(short)97) {
      if ((int)$values->[1] == (int)(short)98) {
        if ((int)$values->[2] == (int)(short)Fn->INT16_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  static method spvm_new_int_array_binary_pack : int ($values : int[]) {
    
    if ($values->[0] == (int)97) {
      if ($values->[1] == (int)98) {
        if ($values->[2] == (int)Fn->INT32_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_long_array_binary_pack : int ($values : long[]) {
    
    if ($values->[0] == (long)97) {
      if ($values->[1] == (long)98) {
        if ($values->[2] == (long)Fn->INT64_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_float_array_binary_pack : int ($values : float[]) {
    
    if ($values->[0] == (float)97) {
      if ($values->[1] == (float)98) {
        if ($values->[2] == (float)TestCase::ExchangeAPI->FLOAT_PRECICE()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  static method spvm_new_double_array_binary_pack : int ($values : double[]) {
    
    if ($values->[0] == (double)97) {
      if ($values->[1] == (double)98) {
        if ($values->[2] == (double)TestCase::ExchangeAPI->DOUBLE_PRECICE()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  

  static method spvm_new_object_array_len_element_any_object_array : int ($nums : TestCase[]) {
    if ($nums->[0]{x_int} == 1) {
      if ($nums->[1]{x_int} == 2) {
        return 1;
      }
    }
    
    return 0;
  }

  static method spvm_new_object_array_len_element_byte_array : int ($nums : byte[][]) {
    
    if ($nums->[0][0] == 1) {
      if ($nums->[0][1] == 2) {
        if ($nums->[0][2] == 3) {
          if ($nums->[1][0] == 4) {
            if ($nums->[1][1] == 5) {
              if ($nums->[1][2] == 6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_object_array_len_element_short_array : int ($nums : short[][]) {
    if ((int)$nums->[0][0] == (int)(short)1) {
      if ((int)$nums->[0][1] == (int)(short)2) {
        if ((int)$nums->[0][2] == (int)(short)3) {
          if ((int)$nums->[1][0] == (int)(short)4) {
            if ((int)$nums->[1][1] == (int)(short)5) {
              if ((int)$nums->[1][2] == (int)(short)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_object_array_len_element_int_array : int ($nums : int[][]) {
    if ($nums->[0][0] == 1) {
      if ($nums->[0][1] == 2) {
        if ($nums->[0][2] == 3) {
          if ($nums->[1][0] == 4) {
            if ($nums->[1][1] == 5) {
              if ($nums->[1][2] == 6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_object_array_len_element_long_array : int ($nums : long[][]) {
    if ($nums->[0][0] == (long)1) {
      if ($nums->[0][1] == (long)2) {
        if ($nums->[0][2] == (long)3) {
          if ($nums->[1][0] == (long)4) {
            if ($nums->[1][1] == (long)5) {
              if ($nums->[1][2] == (long)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_object_array_len_element_float_array : int ($nums : float[][]) {
    if ($nums->[0][0] == (float)1) {
      if ($nums->[0][1] == (float)2) {
        if ($nums->[0][2] == (float)3) {
          if ($nums->[1][0] == (float)4) {
            if ($nums->[1][1] == (float)5) {
              if ($nums->[1][2] == (float)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_object_array_len_element_double_array : int ($nums : double[][]) {
    if ($nums->[0][0] == (double)1) {
      if ($nums->[0][1] == (double)2) {
        if ($nums->[0][2] == (double)3) {
          if ($nums->[1][0] == (double)4) {
            if ($nums->[1][1] == (double)5) {
              if ($nums->[1][2] == (double)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  # SPVM set and get
  static method spvm_set_and_get_byte : int ($nums : byte[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == Fn->INT8_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  static method spvm_set_and_get_short : int ($nums : short[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == Fn->INT16_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  static method spvm_set_and_get_int : int ($nums : int[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == Fn->INT32_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  static method spvm_set_and_get_long : int ($nums : long[]) {
    
    if ($nums->[0] == 0L) {
      if ($nums->[1] == Fn->INT64_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  static method spvm_set_and_get_float : int ($nums : float[]) {
    
    if ($nums->[0] == 0.0f) {
      if ($nums->[1] == TestCase::ExchangeAPI->FLOAT_PRECICE()) {
        return 1;
      }
    }
    
    return 0;
  }
  static method spvm_set_and_get_double : int ($nums : double[]) {
    
    if ($nums->[0] == 0.0) {
      if ($nums->[1] == TestCase::ExchangeAPI->DOUBLE_PRECICE()) {
        return 1;
      }
    }
    
    return 0;
  }

  static method spvm_set_and_get_mulnum_t_int : int ($points : TestCase::Point_3i[]) {
    
    if ($points->[1]{x} == Fn->INT32_MIN()) {
      if ($points->[1]{y} == 1) {
        if ($points->[1]{z} == 2) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_byte : int ($points : TestCase::Point_3b[]) {
    
    if ($points->[0]{x} == Fn->INT8_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_short : int ($points : TestCase::Point_3s[]) {
    
    if ($points->[0]{x} == Fn->INT16_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_int : int ($points : TestCase::Point_3i[]) {
    
    if ($points->[0]{x} == Fn->INT32_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_long : int ($points : TestCase::Point_3l[]) {
    
    if ($points->[0]{x} == Fn->INT64_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_float : int ($points : TestCase::Point_3f[]) {
    
    if ($points->[0]{x} == Fn->FLT_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_double : int ($points : TestCase::Point_3d[]) {
    
    if ($points->[0]{x} == Fn->DBL_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_binary_byte : int ($points : TestCase::Point_3b[]) {
    if ($points->[0]{x} == Fn->INT8_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_binary_short : int ($points : TestCase::Point_3s[]) {
    if ($points->[0]{x} == Fn->INT16_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_binary_int : int ($points : TestCase::Point_3i[]) {
    if ($points->[0]{x} == Fn->INT32_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_binary_long : int ($points : TestCase::Point_3l[]) {
    if ($points->[0]{x} == Fn->INT64_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_binary_float : int ($points : TestCase::Point_3f[]) {
    if ($points->[0]{x} == Fn->FLT_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  static method spvm_new_mulnum_array_binary_double : int ($points : TestCase::Point_3d[]) {
    if ($points->[0]{x} == Fn->DBL_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  
  static method arg_array_of_any_object : int ($objects : object[]) {
    my $int_object = (Int)$objects->[0];
    my $double_object = (Double)$objects->[1];
    
    unless ($int_object->value == 1) {
      return 0;
    }
    
    unless ($double_object->value == 3) {
      return 0;
    }
    
    return 1;
  }
}