package TestCase::Lib::SPVM::CORE {
  use TestCase::Minimal;

  sub test_split : int () {
    {
      my $str = "foo,bar,baz";
      my $split_strs = split(",", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $str = "foo,bar,";
      my $split_strs = split(",", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", ""])) {
        return 0;
      }
    }

    {
      my $str = ",foo,,bar,,";
      my $split_strs = split(",", $str, -1);
      unless (equals_strarray($split_strs, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }

    {
      my $str = "foo : bar : baz";
      my $split_strs = split(" : ", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $str = "foo : bar : ";
      my $split_strs = split(" : ", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", ""])) {
        return 0;
      }
    }
    {
      my $str = " : foo :  : bar :  : ";
      my $split_strs = split(" : ", $str, -1);
      unless (equals_strarray($split_strs, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }

    {
      my $str = "foo---bar---baz";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $str = "foo---bar---";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", ""])) {
        return 0;
      }
    }
    {
      my $str = "---foo------bar------";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }

    {
      my $str = "foo--!bar---baz";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["foo--!bar", "baz"])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_fgets : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    {
      my $line = fgets($fh);
      unless ($line eq "abcd\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line eq "fghi\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line eq "klm\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_fgets_while : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    my $lstrings = new_list([]);
    while (my $line = fgets($fh)) {
      $lstrings->push($line);
    }
    my $strings = $lstrings->to_strarray;
    
    unless (equals_strarray($strings, ["abcd\n", "fghi\n", "klm\n"])) {
      return 0;
    }
    
    return 1;
  }

  sub test_fgets_eof : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    {
      my $line = fgets($fh);
      unless ($line eq "abcd\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line eq "fghi\n") {
        return 0;
      }
    }
    
    {
      my $line = fgets($fh);
      unless ($line eq "\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_fgets_long_line : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    {
      my $line = fgets($fh);
      unless ($line eq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line eq "fghi\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line eq "klm\n") {
        return 0;
      }
    }

    {
      my $line = fgets($fh);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_fgets_chomp : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    {
      my $line = fgets_chomp($fh);
      unless ($line eq "abcd") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line eq "fghi") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_fgets_chomp_while : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    my $lstrings = new_list([]);
    while (my $line = fgets_chomp($fh)) {
      $lstrings->push($line);
    }
    my $strings = $lstrings->to_strarray;
    
    unless (equals_strarray($strings, ["abcd", "fghi", "klm"])) {
      return 0;
    }
    
    return 1;
  }

  sub test_fgets_chomp_eof : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    {
      my $line = fgets_chomp($fh);
      unless ($line eq "abcd") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line eq "fghi") {
        return 0;
      }
    }
    
    {
      my $line = fgets_chomp($fh);
      unless ($line eq "") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_fgets_chomp_long_line : int ($file : string) {
    my $fh = fopen($file, "r");
    unless ($fh) {
      die "Can't open file $file";
    }
    
    {
      my $line = fgets_chomp($fh);
      unless ($line eq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line eq "fghi") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = fgets_chomp($fh);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }
  
  sub test_init_native_constants : int () {
    {
      my $int_constants = [
        O_RDONLY(),
        O_WRONLY(),
        O_RDWR(),
        O_APPEND(),
        O_CREAT(),
        O_TRUNC(),
        SEEK_SET(),
        SEEK_CUR(),
        SEEK_END(),
        EOF(),
      ];
      
      my $ret = test_init_native_constants_native($int_constants);
      
      unless ($ret) {
        return 0;
      }
    }
    
    return 1;
  }

  native sub test_init_native_constants_native : int ($int_constants : int[]);

  sub test_slurp_file : int ($file : string) {
    {
      my $string = slurp_file($file);
      
      unless ($string eq "abcd\nfghi\nklm\n") {
        return 0;
      }
    }
    
    return 1;
  }
  
  sub test_fopen : int ($file : string) {
    {
      my $fh = fopen($file, "r");
      unless ($fh) {
        return 0;
      }
    }
    
    {
      my $fh = fopen($file, "ppp");
      if ($fh) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_fclose : int ($file : string) {
    {
      my $fh = fopen($file, "r");
      unless ($fh) {
        return 0;
      }
      my $ret = fclose($fh);
      unless ($ret == 0) {
        return 0;
      }
    }
    
    {
      my $ret = fclose(undef);
      unless ($ret == SPVM::CORE->EOF()) {
        return 0;
      }
    }

    return 1;
  }

  sub test_fread : int ($file : string) {
    {
      my $fh = fopen($file, "r");
      unless ($fh) {
        die "Can't open file $file";
      }
      
      my $buffer = new byte[5];
      {
        my $read_length = fread($buffer, $fh);
        unless ($buffer eq "abcd\n") {
          return 0;
        }
        unless ($read_length == 5) {
          return 0;
        }
      }
      
      {
        my $read_length = fread($buffer, $fh);
        unless ($buffer eq "fghi\n") {
          return 0;
        }
        unless ($read_length == 5) {
          return 0;
        }
      }
      {
        my $read_length = fread($buffer, $fh);
        unless (sliceb($buffer, 0, 4) eq "klm\n") {
          return 0;
        }
        unless ($read_length == 4) {
          return 0;
        }
      }
    }

    return 1;
  }

  sub test_fwrite : int ($file : string) {
    {
      my $fh = fopen($file, "w");
      unless ($fh) {
        die "Can't open file $file";
      }
      {
        my $write_length = fwrite("abcd\n", $fh);
        unless ($write_length == 5) {
          return 0;
        }
      }
      {
        my $write_length = fwrite("fg", $fh);
        unless ($write_length == 2) {
          return 0;
        }
      }
    }
    
    my $content = slurp_file($file);
    unless ($content eq "abcd\nfg") {
      return 0;
    }

    return 1;
  }

  sub test_join : int () {
    my $strings = ["abc", "def", "hij"];
    
    my $join = join(",", $strings);
    
    if ($join eq "abc,def,hij") {
      return 1;
    }
    
    return 0;
  }

  sub test_sin : int () {
    my $value = sin(PI());
    
    if ($value < 0.000001 && $value > -0.000001) {
      return 1;
    }
    return 0;
  }

  sub test_cos : int () {
    my $value = cos(PI() / 2.0);
    
    if ($value < 0.000001 && $value > -0.000001) {
      return 1;
    }
    return 0;
  }
  
  sub test_tan : int () {
    my $value = tan(PI() / 4.0);
    
    if ($value - 1.0 < 0.000001 && $value - 1.0 > -0.000001) {
      return 1;
    }
    return 0;
  }

  sub test_isinff: int () {
    if (isinff(INFINITYF())) {
      if (!isinff(NANF())) {
        if (!isinff(0.1f)) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub test_isfinitef: int () {
    if (!isfinitef(INFINITYF())) {
      if (!isfinitef(NANF())) {
        if (isfinitef(0.1f)) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub test_isnanf: int () {
    if (!isnanf(INFINITYF())) {
      if (isnanf(NANF())) {
        if (!isnanf(0.1f)) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  sub test_float_pass_positive_infinity : int ($value : float) {
    if ($value == INFINITYF()) {
      return 1;
    }
    
    return 0;
  }
  
  sub test_float_pass_nan : int ($value : float) {
    if (isnanf($value)) {
      return 1;
    }
    
    return 0;
  }

  sub test_isinf : int () {
    if (isinf(INFINITY())) {
      if (!isinf(NAN())) {
        if (!isinf(0.1)) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub test_isfinite : int () {
    if (!isfinite(INFINITY())) {
      if (!isfinite(NAN())) {
        if (isfinite(0.1)) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub test_isnan : int () {
    if (!isnan(INFINITY())) {
      if (isnan(NAN())) {
        if (!isnan(0.1)) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  sub test_double_pass_nan : int ($value : double) {
    if (isnan($value)) {
      return 1;
    }
    
    return 0;
  }
  
  sub test_double_pass_positive_infinity : int ($value : double) {
    if ($value == INFINITY()) {
      return 1;
    }
    
    return 0;
  }

  sub test_byte_constant : int () {
    if ((int)INT8_MIN() == (int)(byte)-128) {
      if ((int)INT8_MAX() == (int)(byte)127) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_short_constant : int () {
    if ((int)INT16_MIN() == (int)(short)-32768) {
      if ((int)INT16_MAX() == (int)(short)32767) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_int_constant : int () {
    if (INT32_MIN() == -2147483648) {
      if (INT32_MAX() == 2147483647) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_long_constant : int () {
    if (INT64_MIN() == -9223372036854775808L) {
      if (INT64_MAX() == 9223372036854775807L) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_new_oarray_proto : int () {
    my $minimals = new TestCase::Minimal[1];
    
    my $new_oarray = new_oarray_proto($minimals, 2);
    unless ($new_oarray isa TestCase::Minimal[]) {
      return 0;
    }
    my $new_minimals = (TestCase::Minimal[])$new_oarray;
    unless (@$new_minimals == 2) {
      return 0;
    }
    
    return 1;
  }
  sub test_sliceb : int () {
    {
      my $nums = [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19];
      my $slice = sliceb($nums, 0, 7);
      unless (equals_barray($slice, [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    
    {
      my $nums = [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19];
      my $slice = sliceb($nums, 1, 3);
      unless (equals_barray($slice, [(byte)-7, 9, INT8_MIN()])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_slices : int () {
    {
      my $nums = [(short)5, -7, 9, INT16_MIN(), 127, 15, 19];
      my $slice = slices($nums, 0, 7);
      unless (equals_sarray($slice, [(short)5, -7, 9, INT16_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(short)5, -7, 9, INT16_MIN(), 127, 15, 19];
      my $slice = slices($nums, 1, 3);
      unless (equals_sarray($slice, [(short)-7, 9, INT16_MIN()])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_slicei : int () {
    {
      my $nums = [(int)5, -7, 9, INT32_MIN(), 127, 15, 19];
      my $slice = slicei($nums, 0, 7);
      unless (equals_iarray($slice, [(int)5, -7, 9, INT32_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(int)5, -7, 9, INT32_MIN(), 127, 15, 19];
      my $slice = slicei($nums, 1, 3);
      unless (equals_iarray($slice, [(int)-7, 9, INT32_MIN()])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_slicel : int () {
    {
      my $nums = [(long)5, -7, 9, INT64_MIN(), 127, 15, 19];
      my $slice = slicel($nums, 0, 7);
      unless (equals_larray($slice, [(long)5, -7, 9, INT64_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(long)5, -7, 9, INT64_MIN(), 127, 15, 19];
      my $slice = slicel($nums, 1, 3);
      unless (equals_larray($slice, [(long)-7, 9, INT64_MIN()])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_slicef : int () {
    {
      my $nums = [(float)5, -7, 9, FLT_MIN(), 127, 15, 19];
      my $slice = slicef($nums, 0, 7);
      unless (equals_farray($slice, [(float)5, -7, 9, FLT_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(float)5, -7, 9, FLT_MIN(), 127, 15, 19];
      my $slice = slicef($nums, 1, 3);
      unless (equals_farray($slice, [(float)-7, 9, FLT_MIN()])) {
        return 0;
      }
    }
    
    
    return 1;
  }
  sub test_sliced : int () {
    {
      my $nums = [(double)5, -7, 9, DBL_MIN(), 127, 15, 19];
      my $slice = sliced($nums, 0, 7);
      unless (equals_darray($slice, [(double)5, -7, 9, DBL_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(double)5, -7, 9, DBL_MIN(), 127, 15, 19];
      my $slice = sliced($nums, 1, 3);
      unless (equals_darray($slice, [(double)-7, 9, DBL_MIN()])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_sliceo : int () {
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      my $minimal4 = TestCase::Minimal->new;
      
      my $elems = [$minimal1, $minimal2, $minimal3, $minimal4];
      my $slice = (TestCase::Minimal[])sliceo($elems, 0, 4);
      unless (equals_oarray($slice, [$minimal1, $minimal2, $minimal3, $minimal4])) {
        return 0;
      }
    }
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      my $minimal4 = TestCase::Minimal->new;
      
      my $elems = [$minimal1, $minimal2, $minimal3, $minimal4];
      my $slice = (TestCase::Minimal[])sliceo($elems, 1, 2);
      unless (equals_oarray($slice, [$minimal2, $minimal3])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_reverseb : int () {
    {
      my $nums = [(byte)1, 3, INT8_MAX()];
      reverseb($nums);
      unless (equals_barray($nums, [(byte)INT8_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(byte)1, 3, 5, INT8_MAX()];
      reverseb($nums);
      unless (equals_barray($nums, [(byte)INT8_MAX(), 5, 3, 1])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_reverses : int () {
    {
      my $nums = [(short)1, 3, INT16_MAX()];
      reverses($nums);
      unless (equals_sarray($nums, [(short)INT16_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(short)1, 3, 5, INT16_MAX()];
      reverses($nums);
      unless (equals_sarray($nums, [(short)INT16_MAX(), 5, 3, 1])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_reversei : int () {
    {
      my $nums = [(int)1, 3, INT32_MAX()];
      reversei($nums);
      unless (equals_iarray($nums, [(int)INT32_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(int)1, 3, 5, INT32_MAX()];
      reversei($nums);
      unless (equals_iarray($nums, [(int)INT32_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_reversel : int () {
    {
      my $nums = [(long)1, 3, INT64_MAX()];
      reversel($nums);
      unless (equals_larray($nums, [(long)INT64_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(long)1, 3, 5, INT64_MAX()];
      reversel($nums);
      unless (equals_larray($nums, [(long)INT64_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    
    
    return 1;
  }
  sub test_reversef : int () {
    {
      my $nums = [(float)1, 3, FLT_MAX()];
      reversef($nums);
      unless (equals_farray($nums, [(float)FLT_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(float)1, 3, 5, FLT_MAX()];
      reversef($nums);
      unless (equals_farray($nums, [(float)FLT_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_reversed : int () {
    {
      my $nums = [(double)1, 3, DBL_MAX()];
      reversed($nums);
      unless (equals_darray($nums, [(double)DBL_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(double)1, 3, 5, DBL_MAX()];
      reversed($nums);
      unless (equals_darray($nums, [(double)DBL_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_reverseo : int () {
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      
      my $nums = [$minimal1, $minimal2, $minimal3];
      reverseo($nums);
      unless (equals_oarray($nums, [$minimal3, $minimal2, $minimal1])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_sortb : int () {
    {
      my $nums = [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19];
      sortb($nums);
      unless (equals_barray($nums, [(byte)INT8_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_sorts : int () {
    {
      my $nums = [(short)5, -7, 9, INT16_MIN(), 127, 15, 19];
      sorts($nums);
      unless (equals_sarray($nums, [(short)INT16_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_sorti : int () {
    {
      my $nums = [(int)5, -7, 9, INT32_MIN(), 127, 15, 19];
      sorti($nums);
      unless (equals_iarray($nums, [(int)INT32_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_sortl : int () {
    {
      my $nums = [(long)5, -7, 9, INT64_MIN(), 127, 15, 19];
      sortl($nums);
      unless (equals_larray($nums, [(long)INT64_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_sortf : int () {
    {
      my $nums = [(float)5, -7, 9, FLT_MIN(), 127, 15, 19];
      sortf($nums);
      unless (equals_farray($nums, [(float)-7, FLT_MIN(), 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_sortd : int () {
    {
      my $nums = [(double)5, -7, 9, DBL_MIN(), 127, 15, 19];
      sortd($nums);
      unless (equals_darray($nums, [(double)-7, DBL_MIN(), 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_sorto : int () {
    {
      my $m10 = TestCase::Minimal->newp(10, 419);
      my $m11 = TestCase::Minimal->newp(11, 366);
      my $m12 = TestCase::Minimal->newp(12, 402);
      my $m13 = TestCase::Minimal->newp(13, 453);
      my $m14 = TestCase::Minimal->newp(14, 419);
      my $m15 = TestCase::Minimal->newp(15, 402);
      
      my $ms = [$m10, $m11, $m12, $m13, $m14, $m15];
      sorto($ms, sub : int ($self : self, $x1 : object, $x2 : object) {
        my $m1 = (TestCase::Minimal)$x1;
        my $m2 = (TestCase::Minimal)$x2;
        if ($m1->y > $m2->y) {
          return 1;
        }
        elsif ($m1->y < $m2->y) {
          return -1;
        }
        else {
          return 0;
        }
      });
      unless (equals_oarray($ms, [$m11, $m12, $m15, $m10, $m14, $m13])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_equals_barray : int () {
    my $nums1 = [(byte)0, 1, INT8_MIN()];
    my $nums2 = [(byte)0, 1, INT8_MIN()];
    my $nums3 = [(byte)0, 1];
    my $nums4 = [(byte)0, 1, 2];
    {
      my $is_equals = equals_barray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_barray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_barray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_sarray : int () {
    my $nums1 = [(short)0, 1, INT16_MIN()];
    my $nums2 = [(short)0, 1, INT16_MIN()];
    my $nums3 = [(short)0, 1];
    my $nums4 = [(short)0, 1, 2];
    
    {
      my $is_equals = equals_sarray($nums1, $nums2);
      
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_sarray($nums1, $nums3);
      
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_sarray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_iarray : int () {
    my $nums1 = [(int)0, 1, INT32_MIN()];
    my $nums2 = [(int)0, 1, INT32_MIN()];
    my $nums3 = [(int)0, 1];
    my $nums4 = [(int)0, 1, 2];
    
    {
      my $is_equals = equals_iarray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_iarray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_iarray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_larray : int () {
    my $nums1 = [(long)0, 1, INT64_MIN()];
    my $nums2 = [(long)0, 1, INT64_MIN()];
    my $nums3 = [(long)0, 1];
    my $nums4 = [(long)0, 1, 2];
    
    {
      my $is_equals = equals_larray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_larray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_larray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_farray : int () {
    my $nums1 = [0.0f, 1.5f, FLT_MIN()];
    my $nums2 = [0.0f, 1.5f, FLT_MIN()];
    my $nums3 = [0.0f, 1.5f];
    my $nums4 = [(float)0.0f, 1.5f, 0.5f];
    
    {
      my $is_equals = equals_farray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_farray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_farray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_darray : int () {
    my $nums1 = [0.0, 1.5, DBL_MIN()];
    my $nums2 = [0.0, 1.5, DBL_MIN()];
    my $nums3 = [0.0, 1.5];
    my $nums4 = [(double)0.0, 1.5, 0.5];
    
    {
      my $is_equals = equals_darray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_darray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_darray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_oarray : int () {
    my $minimal1 = TestCase::Minimal->new;
    my $minimal2 = TestCase::Minimal->new;
    my $minimal3 = TestCase::Minimal->new;
    my $minimal4 = TestCase::Minimal->new;
    my $nums1 = [$minimal1, $minimal2, $minimal3];
    my $nums2 = [$minimal1, $minimal2, $minimal3];
    my $nums3 = [$minimal1, $minimal2];
    my $nums4 = [$minimal1, $minimal2, $minimal4];
    my $nums5 = [(object)$minimal1, $minimal2, $minimal3];
    
    {
      my $is_equals = equals_oarray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_oarray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_oarray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_oarray($nums1, $nums5);
      unless ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }


  sub test_equals_strarray : int () {
    my $strings1 = ["abc", "def", "ghi"];
    my $strings2 = ["abc", "def", "ghi"];
    my $strings3 = ["abc", "def"];
    my $strings4 = ["abc", "def", "xxx"];
    
    {
      my $is_equals = equals_strarray($strings1, $strings2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_strarray($strings1, $strings3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_strarray($strings1, $strings4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }
  

  sub test_type_name : int () {
    my $minimal = TestCase::Minimal->new;
    my $type_name = type_name($minimal);
    
    unless ($type_name eq "TestCase::Minimal") {
      return 0;
    }
    
    return 1;
  }
  
  sub test_copy_str : int () {
    my $string = "abc";
    my $string_out = copy_str($string);
    
    unless ($string_out eq "abc") {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_barray : int () {
    my $nums = [(byte)1, 2, INT8_MIN()];
    my $nums_out = copy_barray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT8_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_sarray : int () {
    my $nums = [(short)1, 2, INT16_MIN()];
    my $nums_out = copy_sarray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT16_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_iarray : int () {
    my $nums = [(int)1, 2, INT32_MIN()];
    my $nums_out = copy_iarray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT32_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_larray : int () {
    my $nums = [(long)1, 2, INT64_MIN()];
    my $nums_out = copy_larray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT64_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_farray : int () {
    my $nums = [(float)0.5f, 0.25f, FLT_MIN()];
    my $nums_out = copy_farray($nums);
    
    unless ($nums->[0] == 0.5) {
      return 0;
    }
    
    unless ($nums->[1] == 0.25) {
      return 0;
    }
    
    unless ($nums->[2] == FLT_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_darray : int () {
    my $nums = [(double)0.5, 0.25, DBL_MIN()];
    my $nums_out = copy_darray($nums);
    
    unless ($nums->[0] == 0.5) {
      return 0;
    }
    
    unless ($nums->[1] == 0.25) {
      return 0;
    }
    
    unless ($nums->[2] == DBL_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_oarray : int () {
    my $objects = [(object)SPVM::Int->new(1), SPVM::Int->new(2), SPVM::Int->new(INT32_MIN())];
    my $objects_out = copy_oarray($objects);

    unless ($objects->[0] == $objects_out->[0]) {
      return 0;
    }
    
    unless ($objects->[1] == $objects_out->[1]) {
      return 0;
    }
    
    unless ($objects->[2] == $objects_out->[2]) {
      return 0;
    }
    
    unless ((int)$objects->[0] == 1) {
      return 0;
    }
    
    unless ((int)$objects->[1] == 2) {
      return 0;
    }
    
    unless ((int)$objects->[2] == INT32_MIN()) {
      return 0;
    }
    
    unless (@$objects_out == 3) {
      return 0;
    }
    
    unless ($objects != $objects_out) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_strarray : int () {
    my $strings = ["abc", "def", "hij"];
    my $strings_out = copy_strarray($strings);
    
    unless ($strings->[0] eq $strings_out->[0]) {
      return 0;
    }
    
    unless ($strings->[1] == $strings_out->[1]) {
      return 0;
    }
    
    unless ($strings->[2] == $strings_out->[2]) {
      return 0;
    }
    
    unless (@$strings_out == 3) {
      return 0;
    }
    
    return 1;
  }
}
