package TestCase {
  use Std;

  use TestCase::Weaken;
  use TestCase::Minimal;
  use TestCase::Destructor;
  use TestCase::Empty;
  use TestCase::Private;

  use Byte;
  use Short;
  use Int;
  use Long;
  use Float;
  use Double;

  use Std::Math;
  use Std::TypeUtil;

  our $PACKAGE_VAR_INT : int;
  our $PACKAGE_VAR_LONG : long;
  our $PACKAGE_VAR_MINIMAL : TestCase::Minimal;

  our $PACKAGE_VAR_INT2 : int;
  our $PACKAGE_VAR_LONG2 : long;
  our $PACKAGE_VAR_MINIMAL2 : TestCase::Minimal;

  has x_byte : byte;
  has x_short : short;
  has x_int : int;
  has x_long : long;
  has x_float : float;
  has x_double : double;
  has x_int_array : int[];
  has x_string : byte[];
  has x_test_case : TestCase;
  has x_weaken : TestCase::Weaken;
  has weaken1 : TestCase::Weaken;
  has weaken2 : TestCase::Weaken;
  has weaken3 : TestCase::Weaken;
  has weaken4 : TestCase::Weaken;
  has minimal : TestCase::Minimal;
  has private_field : private int;
  
  sub INT : int () { return 127; }
  sub FLOAT_PRECICE : float () { return 16384.5f; }
  sub DOUBLE_PRECICE : double () { return 65536.5; }
  
  sub get_private_field : int ($self : self) {
    return $self->{private_field};
  }
  
  sub set_x_int_array : void ($self : self, $x_int_array : int[]) {
    $self->{x_int_array} = $x_int_array;
  }

  sub set_x_string : void ($self : self, $x_string : byte[]) {
    $self->{x_string} = $x_string;
  }

  sub set_x_byte : void ($self : self, $x_byte : byte) {
    $self->{x_byte} = $x_byte;
  }

  sub set_x_short : void ($self : self, $x_short : short) {
    $self->{x_short} = $x_short;
  }

  sub set_x_int : void ($self : self, $x_int : int) {
    $self->{x_int} = $x_int;
  }

  sub set_x_long : void ($self : self, $x_long : long) {
    $self->{x_long} = $x_long;
  }

  sub set_x_float : void ($self : self, $x_float : float) {
    $self->{x_float} = $x_float;
  }

  sub set_x_double : void ($self : self, $x_double : double) {
    $self->{x_double} = $x_double;
  }

  sub get_x_byte : byte ($self : self) {
    return $self->{x_byte};
  }

  sub get_x_short : short ($self : self) {
    return $self->{x_short};
  }

  sub get_x_int : int ($self : self) {
    return $self->{x_int};
  }

  sub get_x_long : long ($self : self) {
    return $self->{x_long};
  }

  sub get_x_float : float ($self : self) {
    return $self->{x_float};
  }

  sub get_x_double : double ($self : self) {
    return $self->{x_double};
  }
  
  # Only compile check
  sub eval_block_stack_check : void () {
    eval {
      my $obj_error1 = "Error1";
      
      croak $obj_error1;
    };
    
    {
      my $obj_error2 = "Error2";
      
      croak $obj_error2;
    }
  }
  
  sub new : TestCase () {
    return new TestCase;
  }
  
  sub my_var_in_loop_free : int () {
    for (my $i = 0; $i < 5; $i++) {
      my $minimal = new TestCase::Minimal;
    }
  }
  
  sub next_statement : int () {
    my $total = 0;
    for (my $i = 0; $i < 5; $i++) {
      if ($i == 1) {
        next;
      }
      if ($i == 3) {
        next;
      }
      $total += $i;
    }
    if ($total == 6) {
      return 1;
    }
    return 0;
  }
  
  sub convert_to_string : int () {
    my $byte_string = (String)(byte)23;
    my $short_string = (String)(short)23;
    my $int_string = (String)23;
    my $long_string = (String)23L;
    my $float_string = (String)0.25000f;
    my $double_string = (String)0.25000;
    
    if ($byte_string eq "23") {
      if ($short_string eq "23") {
        if ($int_string eq "23") {
          if ($long_string eq "23") {
            if ($float_string eq "0.25") {
              if ($double_string eq "0.25") {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  
  sub isa_basic : int () {
    my $minimal = new TestCase::Minimal;
    if ($minimal isa TestCase::Minimal) {
      if (!($minimal isa TestCase)) {
        return 1;
      }
    }
    
    return 0;
  }
  
  sub pre_inc : int () {
    my $value_byte = (byte)0;
    my $value_short = (short)0;
    my $value_int = 0;
    my $value_long = 0L;
    my $value_float = 0.25f;
    my $value_double = 0.25;
    
    my $value_byte2 = ++$value_byte;
    my $value_short2 = ++$value_short;
    my $value_int2 = ++$value_int;
    my $value_long2 = ++$value_long;
    my $value_float2 = ++$value_float;
    my $value_double2 = ++$value_double;
    
    
    if ($value_byte == 1) {
      if ($value_byte2 == 1) {
        if ($value_short == 1) {
          if ($value_short2 == 1) {
            if ($value_int == 1) {
              if ($value_int2 == 1) {
                if ($value_long == 1L) {
                  if ($value_long2 == 1L) {
                    if ($value_float == 1.25f) {
                      if ($value_float2 == 1.25f) {
                        if ($value_double == 1.25) {
                          if ($value_double2 = 1.25) {
                            return 1;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  sub post_inc : int () {
    my $value_byte = (byte)0;
    my $value_short = (short)0;
    my $value_int = 0;
    my $value_long = 0L;
    my $value_float = 0.25f;
    my $value_double = 0.25;
    
    my $value_byte2 = $value_byte++;
    my $value_short2 = $value_short++;
    my $value_int2 = $value_int++;
    my $value_long2 = $value_long++;
    my $value_float2 = $value_float++;
    my $value_double2 = $value_double++;
    
    if ($value_byte == 1) {
      if ($value_byte2 == 0) {
        if ($value_short == 1) {
          if ($value_short2 == 0) {
            if ($value_int == 1) {
              if ($value_int2 == 0) {
                if ($value_long == 1L) {
                  if ($value_long2 == 0L) {
                    if ($value_float == 1.25f) {
                      if ($value_float2 = 0.25f) {
                        if ($value_double == 1.25) {
                          if ($value_double2 == 0.25) {
                            return 1;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  sub pre_dec : int () {
    my $value_byte = (byte)0;
    my $value_short = (short)0;
    my $value_int = 0;
    my $value_long = 0L;
    my $value_float = 0;
    my $value_double = 0L;
    
    my $value_byte2 = --$value_byte;
    my $value_short2 = --$value_short;
    my $value_int2 = --$value_int;
    my $value_long2 = --$value_long;
    my $value_float2 = --$value_float;
    my $value_double2 = --$value_double;
    
    if ($value_byte == -1) {
      if ($value_byte2 == -1) {
        if ($value_short == -1) {
          if ($value_short2 == -1) {
            if ($value_int == -1) {
              if ($value_int2 == -1) {
                if ($value_long == -1L) {
                  if ($value_long2 == -1L) {
                    if ($value_float == -1.0f) {
                      if ($value_float2 == -1.0f) {
                        if ($value_double == -1.0) {
                          if ($value_double2 == -1.0) {
                            return 1;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  sub post_dec : int () {
    my $value_byte = (byte)0;
    my $value_short = (short)0;
    my $value_int = 0;
    my $value_long = 0L;
    my $value_float = 1.25f;
    my $value_double = 1.25;
    
    my $value_byte2 = $value_byte--;
    my $value_short2 = $value_short--;
    my $value_int2 = $value_int--;
    my $value_long2 = $value_long--;
    my $value_float2 = $value_float--;
    my $value_double2 = $value_double--;
    
    if ($value_byte == -1) {
      if ($value_byte2 == 0) {
        if ($value_short == -1) {
          if ($value_short2 == 0) {
            if ($value_int == -1) {
              if ($value_int2 == 0) {
                if ($value_long == -1L) {
                  if ($value_long2 == 0L) {
                    if ($value_float == 0.25f) {
                      if ($value_float2 == 1.25f) {
                        if ($value_double == 0.25) {
                          if ($value_double2 == 1.25) {
                            return 1;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  
  sub package_var : int () {
    if ($TestCase::PACKAGE_VAR_INT == 0) {
      $TestCase::PACKAGE_VAR_INT = Std::TypeUtil->INT_MAX();
      if ($TestCase::PACKAGE_VAR_INT == Std::TypeUtil->INT_MAX()) {
        $TestCase::PACKAGE_VAR_LONG = Std::TypeUtil->LONG_MAX();
        if ($TestCase::PACKAGE_VAR_LONG == Std::TypeUtil->LONG_MAX()) {
          $TestCase::PACKAGE_VAR_MINIMAL = TestCase::Minimal->new();
          
          $TestCase::PACKAGE_VAR_MINIMAL->{x} = 4;
          
          if ($TestCase::PACKAGE_VAR_MINIMAL->{x} == 4) {
            $TestCase::PACKAGE_VAR_MINIMAL = undef;
            return 1;
          }
        }
      }
    }
    return 0;
  }

  sub package_var_rel_name : int () {
    if ($PACKAGE_VAR_INT2 == 0) {
      $PACKAGE_VAR_INT2 = Std::TypeUtil->INT_MAX();
      if ($PACKAGE_VAR_INT2 == Std::TypeUtil->INT_MAX()) {
        $PACKAGE_VAR_LONG2 = Std::TypeUtil->LONG_MAX();
        if ($PACKAGE_VAR_LONG2 == Std::TypeUtil->LONG_MAX()) {
          $PACKAGE_VAR_MINIMAL2 = TestCase::Minimal->new();
          
          $PACKAGE_VAR_MINIMAL2->{x} = 4;
          
          if ($PACKAGE_VAR_MINIMAL2->{x} == 4) {
            $PACKAGE_VAR_MINIMAL2 = undef;
            return 1;
          }
        }
      }
    }
    return 0;
  }

  sub get_field_exception_object_undef : int () {
    
    my $test_case : TestCase = undef;
    
    eval {
      $test_case->{x_byte};
    }
    if ($@) {
      return 1;
      
      eval {
        $test_case->{x_short};
      }
      
      if ($@) {
        return 1;

        eval {
          $test_case->{x_int};
        }
        
        if ($@) {
          eval {
            $test_case->{x_long};
          }
          
          if ($@) {
            eval {
              $test_case->{x_float};
            }
            
            if ($@) {
              eval {
                $test_case->{x_double};
              }
              
              if ($@) {
                eval {
                  $test_case->{x_test_case};
                }
                
                if ($@) {

                  return 1;
                }
              }
            }
          }
        }

      }
      
    }
    
    return 0;
  }
  
  sub set_field_exception_object_undef : int () {
    
    my $test_case : TestCase = undef;
    
    eval {
      $test_case->{x_byte} = (byte)1;
    }
    if ($@) {
      return 1;
      
      eval {
        $test_case->{x_short} = (short)1;
      }
      
      if ($@) {
        return 1;

        eval {
          $test_case->{x_int} = 1;
        }
        
        if ($@) {
          eval {
            $test_case->{x_long} = 1L;
          }
          
          if ($@) {
            eval {
              $test_case->{x_float} = 1f;
            }
            
            if ($@) {
              eval {
                $test_case->{x_double} = 1d;
              }
              
              if ($@) {
                eval {
                  $test_case->{x_test_case} = undef;
                }
                
                if ($@) {

                  return 1;
                }
              }
            }
          }
        }
      }
      
    }
    
    return 0;
  }
  
  sub get_minimal : TestCase::Minimal ($self : self) {
    return $self->{minimal};
  }

  sub set_minimal : void ($self : self, $value : TestCase::Minimal) {
    $self->{minimal} = $value;
  }

  # Resorved word
  sub int : int ($obj : TestCase) {
    
    return 5;
  }
  
  sub use_reserved_word : int () {
    
    my $test_case = new TestCase;
    
    if (TestCase->int($test_case) == 5) {
      if (TestCase->int($test_case) == 5) {
        return 1;
      }
    }
    
    return 0;
  }
  
  # SPVM set and get
  sub spvm_set_and_get_byte : int ($nums : byte[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == Std::TypeUtil->BYTE_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_short : int ($nums : short[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == Std::TypeUtil->SHORT_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_int : int ($nums : int[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == Std::TypeUtil->INT_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_long : int ($nums : long[]) {
    
    if ($nums->[0] == 0L) {
      if ($nums->[1] == Std::TypeUtil->LONG_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_float : int ($nums : float[]) {
    
    if ($nums->[0] == 0.0f) {
      if ($nums->[1] == FLOAT_PRECICE()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_double : int ($nums : double[]) {
    
    if ($nums->[0] == 0.0) {
      if ($nums->[1] == DOUBLE_PRECICE()) {
        return 1;
      }
    }
    
    return 0;
  }
  
  # Concat
  sub concat_special_assign : String () {
    
    my $value = "a";
    
    $value .= "b";
    
    return $value;
  }
  
  sub concat : String () {
    "a" . "b";
    
    my $value = "a" . "b";
    
    return $value;
  }
  
  # String
  sub string_utf8 : String () {
    my $value = "あいうえお";
    
    return $value;
  }
  sub string_empty : String () {
    my $value = "";
    
    return $value;
  }

  sub assign : int () {
    # Constant assignment
    my $success_constant_narrow = 0;
    {
      # narrowing constant byte
      my $value1 : byte = 127;
      my $value2 : byte = -128;
      my $value3 = $value1 + $value2;
      
      # narrowing constant short
      my $value4 : short = 32767;
      my $value5 : short = -32768;
      my $value6 = $value4 + $value5;

      # narrowing constant int
      my $value7 : int = 2147483647L;
      my $value8 : int = -2147483648L;
      my $value9 = $value7 + $value8;
      
      if ($value3 == -1) {
        if ($value6 == -1) {
          if ($value9 == -1) {
            $success_constant_narrow = 1;
          }
        }
      }
    }
    
    # Widning
    my $success_constant_wide = 0;
    {
      my $value1 : short = (byte)127;
      my $value2 : int = (byte)127;
      my $value3 : long = (byte)127;
      my $value4 : float = (byte)127;
      my $value5 : double = (byte)127;
      
      if ($value1 == 127) {
        if ($value2 == 127) {
          if ($value3 == 127) {
            if ($value4 == 127.0f) {
              if ($value5 = 127.0) {
                $success_constant_wide = 1;
              }
            }
          }
        }
      }
    }
    
    # Assign same name variable
    my $success_assign_same_name_variable = 0;
    {
      my $obj = new TestCase::Minimal;
      $obj = $obj;
      $success_assign_same_name_variable = 1;
    }
    
    if ($success_constant_narrow && $success_constant_wide && $success_assign_same_name_variable) {
      return 1;
    }
    
    return 0;
  }
  
  sub special_assign : int () {
    my $num1 = 1;
    $num1 += 4;
    if ($num1 == 5) {
      my $num2 = 5;
      $num2 -= 2;
      if ($num2 == 3) {
        my $num3 = 3;
        $num3 *= 4;
        if ($num3 == 12) {
          my $num4 = 6;
          $num4 /= 2;
          if ($num4 == 3) {
            my $num5 = 10;
            $num5 %= 4;
            if ($num5 == 2) {
              my $num6 = 8;
              $num6 <<= 1;
              if ($num6 == 16) {
                my $num7 = -8;
                $num7 >>= 1;
                if ($num7 == -4) {
                  my $num8 = 0xFFFFFFFF;
                  $num8 >>>= 1;
                  if ($num8 == 0x7FFFFFFF) {
                    my $num9 = 0xFFFFFF00;
                    $num9 &= 0xFF;
                    if ($num9 == 0) {
                      my $num10 = 0xFFFFFF00;
                      $num10 |= 0xFF;
                      if ($num10 == 0xFFFFFFFF) {
                        my $num11 = 0xFFFFFF00;
                        $num11 ^= 0xFFFF;
                        if ($num11 == 0xFFFF00FF) {
                          return 1;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  sub call_sub_args_convertion_stab1 : double ($var1 : byte, $var2 : short, $var3 : int, $var4 : long, $var5 : float, $var6 : double) {
    return ($var1 + $var2 + $var3 + $var4 + $var5 + $var6);
  }
  
  sub call_sub_args_convertion : int () {
    # Constant assignment
    my $success_constant_narrow = 0;
    {
      my $return_value1 = call_sub_args_convertion_stab1(1, 2, 3, 2, 8, 16);
      if ($return_value1 == 32) {
        $success_constant_narrow = 1;
      }
    }
    
    # Widning
    my $success_constant_wide = 0;
    {
      my $return_value1 = call_sub_args_convertion_stab1((byte)1, (byte)2, (byte)3, (byte)2, (byte)8, (byte)16);
      
      if ($return_value1 == 32) {
        $success_constant_wide = 1;
      }
    }
    
    if ($success_constant_narrow && $success_constant_wide) {
      return 1;
    }
    
    return 0;
  }

  sub exception_eval_call_sub : int () {
    eval {
      exception_croak_return_int();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }
  
  sub exception_call_stack : int () {
    exception_croak_return_int();
  }
  
  sub exception_croak_return_byte : byte () {
    croak "Error";
  }
  
  sub exception_croak_return_short : short () {
    croak "Error";
  }
  
  sub exception_croak_return_int : int () {
    croak "Error";
  }
  
  sub exception_croak_return_long : long () {
    croak "Error";
  }
  
  sub exception_croak_return_float : float () {
    croak "Error";
  }
  
  sub exception_croak_return_double : double () {
    croak "Error";
  }
  
  sub exception_croak_return_object : TestCase::Minimal () {
    croak "Error";
  }
  
  sub exception_croak_return_void : void () {
    croak "Error";
  }

  sub exception_croak_return_int_eval_catch : int () {
    eval {
      croak "Error";
    };
    
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_sub_assign : int () {
    my $m = TestCase::Minimal->new();
    $m = TestCase::Minimal->new();
  }
  
  sub call_sub_undef : int ($value : TestCase) {
    
    if ($value == undef) {
      return 1;
    }
    
    return 0;
  }

  sub call_sub_last_camma : int () {
    
    my $total = sum_int(3, 4,);
    
    if ($total == 7) {
      return 1;
    }
    
    return 0;
  }
  
  sub destructor : int () {
    my $minimal = TestCase::Minimal->new();
    destructor_call($minimal);
    
    if ($minimal->{x} == 3) {
      return 1;
    }
    return 0;
  }
  
  sub destructor_call : int ($minimal: TestCase::Minimal) {
    my $dest = TestCase::Destructor->new();
    $dest->{minimal} = $minimal;
  }
  
  sub weaken_target4_weaken_object_assign : int () {
    my $test_case = new TestCase;
    $test_case->{x_int} = 2;
    my $weaken1 = TestCase::Weaken->new();
    my $weaken2 = TestCase::Weaken->new();
    my $weaken3 = TestCase::Weaken->new();
    my $weaken4 = TestCase::Weaken->new();
    
    $test_case->{weaken1} = $weaken1;
    $test_case->{weaken2} = $weaken2;
    $test_case->{weaken3} = $weaken3;
    $test_case->{weaken4} = $weaken4;
    
    $weaken1->{test_case} = $test_case;
    $weaken2->{test_case} = $test_case;
    $weaken3->{test_case} = $test_case;
    $weaken4->{test_case} = $test_case;
    
    $weaken1->weaken_test_case;
    $weaken2->weaken_test_case;
    $weaken3->weaken_test_case;
    $weaken4->weaken_test_case;
    
    $weaken2->{test_case} = undef;
    my $test_case2 = new TestCase;
    $weaken4->{test_case} = $test_case2;
    
    if ($test_case->{x_int} == 2) {
      return 1;
    }
    return 0;
  }
  
  sub weaken_target4 : int () {
    my $test_case = new TestCase;
    $test_case->{x_int} = 2;
    my $weaken1 = TestCase::Weaken->new();
    my $weaken2 = TestCase::Weaken->new();
    my $weaken3 = TestCase::Weaken->new();
    my $weaken4 = TestCase::Weaken->new();
    
    $test_case->{weaken1} = $weaken1;
    $test_case->{weaken2} = $weaken2;
    $test_case->{weaken3} = $weaken3;
    $test_case->{weaken4} = $weaken4;
    
    $weaken1->{test_case} = $test_case;
    $weaken2->{test_case} = $test_case;
    $weaken3->{test_case} = $test_case;
    $weaken4->{test_case} = $test_case;
    
    $weaken1->weaken_test_case;
    $weaken2->weaken_test_case;
    $weaken3->weaken_test_case;
    $weaken4->weaken_test_case;

    if ($test_case->{x_int} == 2) {
      return 1;
    }
    return 0;
  }
  
  sub weaken_weaken_object_undef : int () {
    my $weaken = TestCase::Weaken->new();
    my $test_case = new TestCase;
    $test_case->{x_int} = 2;
    
    $test_case->{x_weaken} = $weaken;
    $weaken->{test_case} = $test_case;
    
    weaken $test_case->{x_weaken};
    $test_case->{x_weaken} = undef;
    
    if ($test_case->{x_weaken} == undef) {
      if ($test_case->{x_int} == 2) {
        return 1;
      }
    }
    return 0;
  }
  
  sub weaken_target_object_undef : int () {
    my $weaken = TestCase::Weaken->new();
    my $test_case = new TestCase;

    $test_case->{x_weaken} = $weaken;
    $weaken->{test_case} = $test_case;
    
    weaken $test_case->{x_weaken};
    $weaken = undef;
    
    if ($test_case->{x_weaken} == undef) {
      return 1;
    }
    return 0;
  }
  
  sub weaken_recursive3 : int () {
    my $weaken = TestCase::Weaken->new();
    my $weaken2 = TestCase::Weaken2->new();
    my $test_case = new TestCase;
    $test_case->{x_weaken} = $weaken;
    $weaken->{weaken2} = $weaken2;
    $weaken2->{test_case} = $test_case;
    
    weaken $test_case->{x_weaken};
    
    return 1;
  }
  
  sub weaken_reference_count1_object : int () {
    my $weaken = TestCase::Weaken->new();
    my $test_case = new TestCase;
    
    $test_case->{x_weaken} = $weaken;
    $weaken = undef;
    weaken $test_case->{x_weaken};
    
    if ($test_case->{x_weaken} == undef) {
      return 1;
    }
    
    return 0;
  }

  sub weaken_recursive_again : void () {
    my $weaken = TestCase::Weaken->new();
    
    # Recuresive reference
    my $test_case = new TestCase;
    $test_case->{x_weaken} = $weaken;
    
    $weaken->{test_case} = $test_case;
    
    weaken $test_case->{x_weaken};
    weaken $test_case->{x_weaken};
  }
  
  sub weaken_recursive : int () {
    my $weaken = TestCase::Weaken->new();
    $weaken->{x1} = 1;
    
    # Recuresive reference
    my $test_case = new TestCase;
    $test_case->{x_weaken} = $weaken;
    $test_case->{x_int} = 2;
    
    $weaken->{test_case} = $test_case;
    
    weaken $test_case->{x_weaken};
    
    if ($weaken->{x1} == 1) {
      if ($test_case->{x_int} == 2) {
        return 1;
      }
    }
    return 0;
  }
  
  sub weaken_self_recuresive : int () {
    my $test_case = new TestCase;
    $test_case->{x_int} = 5;
    
    # Recuresive reference
    $test_case->{x_test_case} = $test_case;
    
    weaken $test_case->{x_test_case};
    
    if ($test_case->{x_int} == 5) {
      return 1;
    }
    
    return 0;
  }

  sub 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;
  }

  sub 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;
  }

  sub 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;
  }

  sub 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;
  }

  sub 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;
  }

  sub 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;
  }

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

  # Call void function
  sub call_void_sub : void ($nums : int[]) {
    $nums->[0] = 5;
  }
  sub call_void : int () {
    my $nums = new int[] {1};
    
    call_void_sub($nums);
    
    if ($nums->[0] == 5) {
      return 1;
    }
    return 0;
  }
  
  # Exception
  sub exception_zero_divide_int : int () {
    1 / 0;
  }

  # Multiply
  sub divide : int () {
    # int
    my $int_success = 0;
    {
      my $value1 : int = 8 / 4;
      my $value2 : int = (byte)8 / 4;
      my $value3 : int = 8 / (byte)4;
      my $value4 : int = (short)8 / 4;
      my $value5 : int = 8 / (short)4;
      my $value6 : int = (byte)8 / (byte)4;
      my $value7 : int = (short)8 / (short)4;
      my $value8 : int = (byte)8 / (short)4;
      my $value9 : int = 8 / 3;
      if ($value1 == 2) {
        if ($value2 == 2) {
          if ($value3 == 2) {
            if ($value4 == 2) {
              if ($value5 == 2) {
                if ($value6 == 2) {
                  if ($value7 == 2) {
                    if ($value8 == 2) {
                      if ($value9 == 2) {
                        $int_success = 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # float
    my $float_success = 0;
    {
      my $value1 : float = 1.0f / 2.0f;
      my $value2 : float = (byte)1 / 2.0f;
      my $value3 : float = 1.0f / (byte)2;
      my $value4 : float = (short)1 / 2.0f;
      my $value5 : float = 1.0f / (short)2;
      my $value6 : float = 1 / 2.0f;
      my $value7 : float = 1.0f / 2;
      if ($value1 == 0.5f) {
        if ($value2 == 0.5f) {
          if ($value3 == 0.5f) {
            if ($value4 == 0.5f) {
              if ($value5 == 0.5f) {
                if ($value6 == 0.5f) {
                  if ($value7 == 0.5f) {
                    $float_success = 1;
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # double
    my $double_success = 0;
    {
      my $value1 : double = 1.0 / 2.0;
      my $value2 : double = (byte)1 / 2.0;
      my $value3 : double = 1.0 / (byte)2;
      my $value4 : double = (short)1 / 2.0;
      my $value5 : double = 1.0 / (short)2;
      my $value6 : double = 1 / 2.0;
      my $value7 : double = 1.0 / 2;
      my $value8 : double = 1.0 / 2.0f;
      my $value9 : double = 1.0f / 2.0;
      if ($value1 == 0.5f) {
        if ($value2 == 0.5f) {
          if ($value3 == 0.5f) {
            if ($value4 == 0.5f) {
              if ($value5 == 0.5f) {
                if ($value6 == 0.5f) {
                  if ($value7 == 0.5f) {
                    if ($value8 == 0.5f) {
                      if ($value9 == 0.5f) {
                        $double_success = 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    if ($int_success && $float_success && $double_success) {
      return 1;
    }

    return 0;
  }
  
  sub remainder : int () {
    my $num1 = (byte)((byte)5 % (byte)3);
    my $num2 = (byte)((byte)-3 % (byte)5);
    my $num3 = (short)((int)(short)5 % (int)(short)3);
    my $num4 = (short)((int)(short)-3 % (int)(short)5);
    my $num5 = 5 % 3;
    my $num6 = -3 % 5;
    my $num7 = 5L % 3L;
    my $num8 = -3L % 5L;
    
    if ($num1 == 2) {
      if ($num2 == -3) {
        if ($num3 == 2) {
          if ($num4 == -3) {
            if ($num5 == 2) {
              if ($num6 == -3) {
                if ($num7 == 2L) {
                  if ($num8 == -3L) {
                    return 1;
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  
  # Default return value empty
  sub default_return_value_byte : int () {
    
    if (default_return_value_byte_sub() == 0) {
      if (default_return_value_byte_sub_empty() == 0) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_byte_sub : byte () {
    1;
  }
  sub default_return_value_byte_sub_empty : byte () {
    
  }
  sub default_return_value_short : int () {
    
    if ((int)default_return_value_short_sub() == (int)(short)0) {
      if ((int)default_return_value_short_sub_empty() == (int)(short)0) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_short_sub : short () {
    1;
  }
  sub default_return_value_short_sub_empty : short () {
    
  }
  sub default_return_value_int : int () {
    
    if (default_return_value_int_sub() == (int)0) {
      if (default_return_value_int_sub_empty() == (int)0) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_int_sub : int () {
    1;
  }
  sub default_return_value_int_sub_empty : int () {
    
  }
  sub default_return_value_long : int () {
    
    if (default_return_value_long_sub() == (long)0) {
      if (default_return_value_long_sub_empty() == (long)0) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_long_sub : long () {
    1;
  }
  sub default_return_value_long_sub_empty : long () {
    
  }
  sub default_return_value_float : int () {
    
    if (default_return_value_float_sub() == (float)0) {
      if (default_return_value_float_sub_empty() == (float)0) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_float_sub : float () {
    1;
  }
  sub default_return_value_float_sub_empty : float () {
    
  }
  sub default_return_value_double : int () {
    
    if (default_return_value_double_sub() == (double)0) {
      if (default_return_value_double_sub_empty() == (double)0) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_double_sub : double () {
    1;
  }
  sub default_return_value_double_sub_empty : double () {
    
  }
  sub default_return_value_object : int () {
    
    if (default_return_value_object_sub() == undef) {
      if (default_return_value_object_sub_empty() == undef) {
        return 1;
      }
    }
    
    return 0;
  }
  sub default_return_value_object_sub : TestCase () {
    1;
  }
  sub default_return_value_object_sub_empty : TestCase () {
    
  }
  
  # Switch - nest
  sub switch_nest : int () {
    my $success1 : int;
    switch (3) {
      case 1:
        $success1 = 0;
        last;
      case 3:
        switch (5) {
          case 2:
            $success1 = 0;
            last;
          case 5:
            $success1 = 1;
            last;
          case 6:
            $success1 = 0;
            last;
          default:
            $success1 = 0;
            last;
        }
        last;
      case 10000:
        $success1 = 0;
        last;
      default:
    }
    
    return $success1;
  }
  
  # Switch - lookup switch
  sub switch_lookup_switch : int () {
    my $success1 : int;
    switch (1) {
      case 1:
        $success1 = 1;
        last;
      case 3:
        $success1 = 0;
        last;
      case 10000:
        $success1 = 0;
        last;
      default:
    }
    my $success2 : int;
    switch (3) {
      case 1:
        $success2 = 0;
        last;
      case 3:
        $success2 = 1;
        last;
      case 10000:
        $success2 = 0;
        last;
      default:
    }
    my $success3 : int;
    switch (10000) {
      case 3:
        $success3 = 0;
        last;
      case 1:
        $success3 = 0;
        last;
      case 10000:
        $success3 = 1;
        last;
      default:
    }
    my $success4 : int;
    switch (2) {
      case 1:
        last;
      case 3:
        last;
      case 10000:
        last;
      default:
        $success4 = 1;
    }
    
    if ($success1) {
      if ($success2) {
        if ($success3) {
          if ($success4) {
            return 1;
          }
        }
      }
    }
    return 0;
  }
  
  # Switch - table switch
  sub switch_table_switch : int () {
    my $success1 : int;
    
    switch(3) {
      case 3:
        $success1 = 1;
        last;
      case 4:
        $success1 = 0;
        last;
      case 5:
        $success1 = 0;
        last;
      default:
    }

    my $success2 : int;
    switch(4) {
      case 3:
        $success2 = 0;
        last;
      case 4:
        $success2 = 1;
        last;
      case 5:
        $success2 = 0;
        last;
      default:
    }
    my $success3 : int;
    switch(10) {
      case 3:
        $success3 = 0;
        last;
      case 4:
        $success3 = 0;
        last;
      case 5:
        $success3 = 0;
        last;
      default:
        $success3 = 1;
    }
    
    if ($success1) {
      if ($success2) {
        if ($success3) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub my_var_scope : int () {
    my $ok1 = 0;
    my $ok2 = 0;
    my $ok3 = 0;
    
    my $var1 = 1;
    my $var2 = 2;
    
    if ($var1 == 1) {
      if ($var2 == 2) {
        $ok1 = 1;
      }
    }
    
    {
      my $var1 = 3;
      my $var2 = 4;
      my $var3 = 5;
      
      if ($var1 == 3) {
        if ($var2 == 4) {
          if ($var3 == 5) {
            $ok2 = 1;
          }
        }
      }
    }
    
    my $var3 = 6;
    
    if ($var1 == 1) {
      if ($var2 == 2) {
        if ($var3 == 6) {
          $ok3 = 1;
        }
      }
    }
    
    if ($ok1) {
      if ($ok2) {
        if ($ok3) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  # My variable is initialized zero
  sub my_var_initialized_zero : int () {
    my $var1 : int;
    my $var2 : TestCase;
    
    if ($var1 == 0) {
      if ($var2 == undef) {
        return 1;
      }
    }
    return 0;
  }

  sub my_var_block : int () {
    my $success = 1;
    
    my $var1 = 1;
    if ($var1 != 1) {
      $success = 0;
    }
    
    {
      my $var1 = 2;
      if ($var1 != 2) {
        $success = 0;
      }
      
      {
        my $var1 = $var1;
        if ($var1 != 2) {
          $success = 0;
        }
        $var1 = 3;
      }
      if ($var1 != 2) {
        $success = 0;
      }
    }
    
    if ($success) {
      return 1;
    }
    return 0;
  }
  
  # Object field is initialized zero
  sub object_field_initialized_zero : int () {
    my $obj = new TestCase;
    if ($obj->{x_byte} == 0) {
      if ($obj->{x_int} == 0) {
        if ($obj->{x_string} == undef) {
          return 1;
        }
      }
    }
    return 0;
  }
  
  # Object field set and get
  sub object_field_set_and_get : int () {
    my $test_case = new TestCase;
    
    $test_case->{x_byte} = Std::TypeUtil->BYTE_MAX();
    $test_case->{x_short} = Std::TypeUtil->SHORT_MAX();
    $test_case->{x_int} = Std::TypeUtil->INT_MAX();
    $test_case->{x_long} = Std::TypeUtil->LONG_MAX();
    $test_case->{x_float} = TestCase->FLOAT_PRECICE();
    $test_case->{x_double} = TestCase->DOUBLE_PRECICE();
    my $minimal = TestCase::Minimal->new();
    $minimal->{x} = 3;
    $test_case->{minimal} = $minimal;
    if ((int)$test_case->{x_byte} == (int)Std::TypeUtil->BYTE_MAX()) {
      if ((int)$test_case->{x_short} == (int)Std::TypeUtil->SHORT_MAX()) {
        if ($test_case->{x_int} == Std::TypeUtil->INT_MAX()) {
          if ($test_case->{x_long} == Std::TypeUtil->LONG_MAX()) {
            if ($test_case->{x_float} == TestCase->FLOAT_PRECICE()) {
              if ($test_case->{x_double} == TestCase->DOUBLE_PRECICE()) {
                if ($test_case->{minimal}->{x} == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    return 0;
  }

  # Object field set and get
  sub object_field_set_and_get_again : int () {
    my $test_case = new TestCase;
    
    $test_case->{x_byte} = Std::TypeUtil->BYTE_MAX();
    $test_case->{x_short} = Std::TypeUtil->SHORT_MAX();
    $test_case->{x_int} = Std::TypeUtil->INT_MAX();
    $test_case->{x_long} = Std::TypeUtil->LONG_MAX();
    $test_case->{x_float} = FLOAT_PRECICE();
    $test_case->{x_double} = DOUBLE_PRECICE();
    my $minimal = TestCase::Minimal->new();
    $minimal->{x} = 3;
    $test_case->{minimal} = $minimal;

    $test_case->{x_byte} = Std::TypeUtil->BYTE_MAX();
    $test_case->{x_short} = Std::TypeUtil->SHORT_MAX();
    $test_case->{x_int} = Std::TypeUtil->INT_MAX();
    $test_case->{x_long} = Std::TypeUtil->LONG_MAX();
    $test_case->{x_float} = FLOAT_PRECICE();
    $test_case->{x_double} = DOUBLE_PRECICE();
    $test_case->{minimal} = $minimal;

    if ((int)$test_case->{x_byte} == (int)Std::TypeUtil->BYTE_MAX()) {
      if ((int)$test_case->{x_short} == (int)Std::TypeUtil->SHORT_MAX()) {
        if ($test_case->{x_int} == Std::TypeUtil->INT_MAX()) {
          if ($test_case->{x_long} == Std::TypeUtil->LONG_MAX()) {
            if ($test_case->{x_float} == FLOAT_PRECICE()) {
              if ($test_case->{x_double} == DOUBLE_PRECICE()) {
                if ($test_case->{minimal}->{x} == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    return 0;
  }

  # new near small base_object_max_byte_size_use_memory_pool
  sub new_near_small_base_object_max_byte_size_use_memory_pool : int () {
    my $block = new byte[0xFFF0];
    
    return 1;
  }

  sub array_default_zero_not_memory_pool : int () {
    my $values_byte = new byte[1000000];
    my $values_short = new short[1000000];
    my $values_int = new int[1000000];
    my $values_long = new long[1000000];
    my $values_float = new float[1000000];
    my $values_double = new double[1000000];
    my $values_object = new TestCase[1000000];
    if ($values_byte->[0] == 0) {
      if ($values_byte->[999999] == 0) {
        if ($values_short->[0] == 0) {
          if ($values_short->[999999] == 0) {
            if ($values_int->[0] == 0) {
              if ($values_int->[999999] == 0) {
                if ($values_long->[0] == 0L) {
                  if ($values_long->[999999] == 0L) {
                    if ($values_float->[0] == 0f) {
                      if ($values_float->[999999] == 0f) {
                        if ($values_double->[0] == 0.0) {
                          if ($values_double->[999999] == 0.0) {
                            return 1;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
        return 1;
      }
    }
    
    return 0;
  }
  sub array_default_zero_memory_pool : int () {
    my $values_byte = new byte[10];
    my $values_short = new short[10];
    my $values_int = new int[10];
    my $values_long = new long[10];
    my $values_float = new float[10];
    my $values_double = new double[10];
    my $values_object = new TestCase[10];
    if ($values_byte->[0] == 0) {
      if ($values_byte->[9] == 0) {
        if ($values_short->[0] == 0) {
          if ($values_short->[9] == 0) {
            if ($values_int->[0] == 0) {
              if ($values_int->[9] == 0) {
                if ($values_long->[0] == 0L) {
                  if ($values_long->[9] == 0L) {
                    if ($values_float->[0] == 0f) {
                      if ($values_float->[9] == 0f) {
                        if ($values_double->[0] == 0.0) {
                          if ($values_double->[9] == 0.0) {
                            return 1;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
        return 1;
      }
    }
    
    return 0;
  }
  sub array_init_byte : int () {
    my $nums = new byte[] {(byte)1, (byte)2, Std::TypeUtil->BYTE_MAX()};
    
    if ($nums->[0] == 1) {
      if ($nums->[1] == 2) {
        if ($nums->[2] == Std::TypeUtil->BYTE_MAX()) {
          return 1;
        }
      }
    }
    return 0;
  }
  sub array_init_short : int () {
    my $nums = new short[] {(short)1, (short)2, (short)3};
    
    if ((int)$nums->[0] == (int)(short)1) {
      if ((int)$nums->[1] == (int)(short)2) {
        if ((int)$nums->[2] == (int)(short)3) {
          return 1;
        }
      }
    }
    return 0;
  }
  sub array_init_int  : int () {
    my $nums = new int[] {1, 2, 3};
    my $nums2 : int[];
    $nums2 = new int[] {4, 5, 6};
    
    my $num3 = [
      [1, 2, 3],
      [4, 5, 6]
    ];
    
    if ($nums->[0] == 1) {
      if ($nums->[1] == 2) {
        if ($nums->[2] == 3) {
          if ($nums2->[0] == 4) {
            if ($nums2->[1] == 5) {
              if ($nums2->[2] == 6) {
                if ($num3->[1][2] == 6) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  sub array_init_long : int () {
    my $nums = new long[] {1L, 2L, 3L};
    
    if ($nums->[0] == 1L) {
      if ($nums->[1] == 2L) {
        if ($nums->[2] == 3L) {
          return 1;
        }
      }
    }
    return 0;
  }
  sub array_init_float : int () {
    my $nums = new float[] {1f, 2f, 3f};
    
    if ($nums->[0] == 1f) {
      if ($nums->[1] == 2f) {
        if ($nums->[2] == 3f) {
          return 1;
        }
      }
    }
    return 0;
  }
  sub array_init_double : int () {
    my $nums = new double[] {1d, 2d, 3d};
    
    if ($nums->[0] == 1d) {
      if ($nums->[1] == 2d) {
        if ($nums->[2] == 3d) {
          return 1;
        }
      }
    }
    return 0;
  }

  sub get_object_from_freelist  : int () {
    get_object_from_freelist_check();
    
    my $result = new int[65];
    $result->[64] = 0;
    
    return 1;
  }
  sub get_object_from_freelist_check : int[] () {
    my $result = new int[63];
    my $true_result = new int[1];
    return $true_result;
  }

  enum {
    INT_ZERO,
    INT_ONE,
    INT_THREE = 3,
    INT_FOUR,
    INT_SIX = 6,
    INT_MINUS_MAX = -2147483648
  }
  sub enum_int  : int () {
    
    if (TestCase->INT_ZERO == 0) {
      if (TestCase->INT_ONE == 1) {
        if (TestCase->INT_THREE == 3) {
          if (TestCase->INT_FOUR == 4) {
            if (TestCase->INT_SIX == 6) {
              if (TestCase->INT_MINUS_MAX == -2147483648) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  
  # Convert type - floating point narrowing convertion
  sub convert_float_to_byte : int () {
    my $value = (byte)127.1f;
    
    if ($value == 127) {
      return 1;
    }
    
    return 0;
  }
  sub convert_float_to_short : int () {
    my $value = (short)32767.1f;
    
    if ($value == 32767) {
      return 1;
    }
    
    return 0;
  }
  sub convert_float_to_int : int () {
    my $value = (int)132767.1f;
    
    if ($value == 132767) {
      return 1;
    }
    
    return 0;
  }
  sub convert_float_to_long : int () {
    my $value = (long)132767.1f;
    
    if ($value == 132767L) {
      return 1;
    }
    
    return 0;
  }
  sub convert_double_to_byte : int () {
    my $value = (byte)127.1;
    
    if ($value == 127) {
      return 1;
    }
    
    return 0;
  }
  sub convert_double_to_short : int () {
    my $value = (short)32767.1;
    
    if ((int)$value == (int)(short)32767) {
      return 1;
    }
    
    return 0;
  }
  sub convert_double_to_int : int () {
    my $value = (int)2147483646.1;
    
    if ($value == 2147483646) {
      return 1;
    }
    
    return 0;
  }
  sub convert_double_to_long : int () {
    my $value = (long)2147483646.1;
    
    if ($value == 2147483646L) {
      return 1;
    }
    
    return 0;
  }
  sub convert_double_to_float : int () {
    my $value = (float)0.5;
    
    if ($value == 0.5f) {
      return 1;
    }
    
    return 0;
  }
  
  # Convert type - floating point widning convertion
  sub convert_byte_to_float : int () {
    my $value = (float)(byte)127;
    
    if ($value == 127.0f) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_float : int () {
    my $value = (float)(short)32767;
    
    if ($value == 32767.0f) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_float : int () {
    my $value = (float)32767;
    
    if ($value == 32767.0f) {
      return 1;
    }
    
    return 0;
  }
  sub convert_long_to_float : int () {
    my $value = (float)32767L;
    
    if ($value == 32767.0f) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_double : int () {
    my $value = (double)(byte)127;
    
    if ($value == 127.0) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_double : int () {
    my $value = (double)(short)32767;
    
    if ($value == 32767.0) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_double : int () {
    my $value = (double)2147483647;
    if ($value == 2147483647.0) {
      return 1;
    }
    
    return 0;
  }
  sub convert_long_to_double : int () {
    my $value = (double)2147483647L;
    
    if ($value == 2147483647.0) {
      return 1;
    }
    
    return 0;
  }
  sub convert_float_to_double : int () {
    my $value = (double)32767.0f;
    
    if ($value == 32767.0) {
      return 1;
    }
    
    return 0;
  }
  
  # Convert type - widning convertion
  sub convert_byte_to_short_plus : int () {
    my $value = (short)(byte)0x7F;
    
    if ((int)$value == (int)(short)0x007F) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_short_minus : int () {
    my $value = (short)(byte)0xFF;
    
    if ((int)$value == (int)(short)0xFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_int_plus : int () {
    my $value = (int)(byte)0x7F;
    
    if ($value == 0x0000007F) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_int_minus : int () {
    my $value = (int)(byte)0xFF;
    
    if ($value == 0xFFFFFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_long_plus : int () {
    my $value = (long)(byte)0x7F;
    
    if ($value == 0x000000000000007FL) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_long_minus : int () {
    my $value = (long)(byte)0xFF;
    
    if ($value == 0xFFFFFFFFFFFFFFFFL) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_int_plus : int () {
    my $value = (int)(short)0x7FFF;
    
    if ($value == 0x0000007FFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_int_minus : int () {
    my $value = (int)(short)0xFFFF;
    
    if ($value == 0xFFFFFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_long_plus : int () {
    my $value = (long)(short)0x7FFF;
    
    if ($value == 0x000000000000007FFFL) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_long_minus : int () {
    my $value = (long)(short)0xFFFF;
    
    if ($value == 0xFFFFFFFFFFFFFFFFL) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_long_plus : int () {
    my $value = (long)0x7FFFFFFF;
    
    if ($value == 0x000000007FFFFFFFL) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_long_minus : int () {
    my $value = (long)0xFFFFFFFF;
    
    if ($value == 0xFFFFFFFFFFFFFFFFL) {
      return 1;
    }
    
    return 0;
  }
  
  # Convert type - convert to same type
  sub convert_long_to_long : int () {
    my $value = (long)0xFFFFFFFFFFFFFFFFL;
    
    if ($value == 0xFFFFFFFFFFFFFFFFL) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_int : int () {
    my $value = (int)0xFFFFFFFF;
    
    if ($value == 0xFFFFFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_short : int () {
    my $value = (short)(short)0xFFFF;
    
    if ((int)$value == (int)(short)0xFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_byte_to_byte : int () {
    my $value = (byte)(byte)0xFF;
    
    if ($value == (byte)0xFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_float_to_float : int () {
    my $value = (float)0.5f;
    
    if ($value == 0.5f) {
      return 1;
    }
    
    return 0;
  }
  sub convert_double_to_double : int () {
    my $value = (double)0.5;
    
    if ($value == 0.5) {
      return 1;
    }
    
    return 0;
  }
  
  # Convert type - integral narrowing convertion
  sub convert_long_to_int : int () {
    my $value = (int)0xFFFFFFFFFFFFFFFFL;
    
    if ($value == 0xFFFFFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_long_to_short : int () {
    my $value = (short)0xFFFFFFFFFFFFFFFFL;
    
    if ((int)$value == (int)(short)0xFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_long_to_byte : int () {
    my $value = (byte)0xFFFFFFFFFFFFFFFFL;
    
    if ((int)$value == (int)(byte)0xFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_short : int () {
    my $value = (short)0xFFFFFFFF;
    
    if ((int)$value == (int)(short)0xFFFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_int_to_byte : int () {
    my $value = (byte)0xFFFFFFFF;
    
    if ((int)$value == (int)(byte)0xFF) {
      return 1;
    }
    
    return 0;
  }
  sub convert_short_to_byte : int () {
    my $value = (byte)(short)0xFFFF;
    
    if ((int)$value == (int)(byte)0xFF) {
      return 1;
    }
    
    return 0;
  }
  
  sub spvm_object_set_object : int ($obj : TestCase) {
    my $nums = $obj->{x_int_array};
    my $values = ($obj->{x_string});
    
    
    # [INT_MAX, INT_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;
  }

  sub 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} == FLOAT_PRECICE()) {
              if ($obj->{x_double} == DOUBLE_PRECICE()) {
                if ($obj->{minimal}->{x} == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  
  sub logical_not_true : int () {
    if (!1) {
      return 0;
    }
    
    return 1;
  }
  sub logical_not_false : int () {
    if (!0) {
      return 1;
    }
    
    return 0;
  }

  # logical or
  sub logical_or_both_true : int () {
    if (1 || 1) {
      return 1;
    }
    
    return 0;
  }
  
  sub logical_or_left_true : int () {
    if (1 || 0) {
      return 1;
    }
    
    return 0;
  }

  sub logical_or_right_true : int () {
    if (0 || 1) {
      return 1;
    }
    
    return 0;
  }

  sub logical_or_both_false : int () {
    if (0 || 0) {
      return 0;
    }
    
    return 1;
  }
  
  # logical and
  sub logical_and_both_true : int () {
    if (1 && 1) {
      return 1;
    }
    
    return 0;
  }
  
  sub logical_and_left_true : int () {
    if (1 && 0) {
      return 0;
    }
    
    return 1;
  }

  sub logical_and_right_true : int () {
    if (1 && 0) {
      return 0;
    }
    
    return 1;
  }

  sub logical_and_both_false : int () {
    if (0 && 0) {
      return 0;
    }
    
    return 1;
  }
  
  # call_sub return value
  sub call_sub_return_byte_array  : byte[] () {
    my $nums = new byte[3];
    
    $nums->[0] = (byte)1;
    $nums->[1] = (byte)2;
    $nums->[2] = (byte)3;
    
    return $nums;
  }
  sub call_sub_return_byte_array_check : int ($nums : byte[]) {
    
    if ($nums->[0] == 1) {
      if ($nums->[1] == 2) {
        if ($nums->[2] == 3) {
          if (@$nums == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

  sub call_sub_return_short_array : short[] () {
    my $nums = new short[3];
    
    $nums->[0] = (short)1;
    $nums->[1] = (short)2;
    $nums->[2] = (short)3;
    
    return $nums;
  }
  sub call_sub_return_short_array_check : int ($nums : short[]) {
    
    if ((int)$nums->[0] == (int)(short)1) {
      if ((int)$nums->[1] == (int)(short)2) {
        if ((int)$nums->[2] == (int)(short)3) {
          if (@$nums == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

  sub call_sub_return_int_array : int[] () {
    my $nums = new int[3];
    
    $nums->[0] = (int)1;
    $nums->[1] = (int)2;
    $nums->[2] = (int)3;
    
    return $nums;
  }
  sub call_sub_return_int_array_check : int ($nums : int[]) {
    
    if ($nums->[0] == (int)1) {
      if ($nums->[1] == (int)2) {
        if ($nums->[2] == (int)3) {
          if (@$nums == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

  sub call_sub_return_long_array : long[] () {
    my $nums = new long[3];
    
    $nums->[0] = (long)1;
    $nums->[1] = (long)2;
    $nums->[2] = (long)3;
    
    return $nums;
  }
  sub call_sub_return_long_array_check : int ($nums : long[]) {
    
    if ($nums->[0] == (long)1) {
      if ($nums->[1] == (long)2) {
        if ($nums->[2] == (long)3) {
          if (@$nums == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

  sub call_sub_return_float_array : float[] () {
    my $nums = new float[3];
    
    $nums->[0] = (float)1;
    $nums->[1] = (float)2;
    $nums->[2] = (float)3;
    
    return $nums;
  }
  sub call_sub_return_float_array_check : int ($nums : float[]) {
    
    if ($nums->[0] == (float)1) {
      if ($nums->[1] == (float)2) {
        if ($nums->[2] == (float)3) {
          if (@$nums == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

  sub call_sub_return_double_array : double[] () {
    my $nums = new double[3];
    
    $nums->[0] = (double)1;
    $nums->[1] = (double)2;
    $nums->[2] = (double)3;
    
    return $nums;
  }
  sub call_sub_return_double_array_check : int ($nums : double[]) {
    
    if ($nums->[0] == (double)1) {
      if ($nums->[1] == (double)2) {
        if ($nums->[2] == (double)3) {
          if (@$nums == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }
  
  # Negate
  sub negate : int () {
    my $num_byte = (byte)1;
    my $num_short = (short)1;
    my $num_int = 1;
    my $num_long = 1L;
    my $num_float = 1f;
    my $num_double = 1d;
    
    my $num_byte_negate : int = -$num_byte;
    my $num_short_negate : int = -$num_short;
    my $num_int_negate = -$num_int;
    my $num_long_negate = -$num_long;
    my $num_float_negate = -$num_float;
    my $num_double_negate = -$num_double;
    
    if ($num_byte_negate == -1) {
      if ($num_short_negate == -1) {
        if ($num_int_negate == -1) {
          if ($num_long_negate == -1L) {
            if ($num_float_negate == -1f) {
              if ($num_double_negate == -1d) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  # Negate
  sub plus : int () {
    my $num_byte = (byte)1;
    my $num_short = (short)1;
    my $num_int = 1;
    my $num_long = 1L;
    my $num_float = 1f;
    my $num_double = 1d;
    
    my $num_byte_plus : int = +$num_byte;
    my $num_short_plus : int = +$num_short;
    my $num_int_plus = +$num_int;
    my $num_long_plus = +$num_long;
    my $num_float_plus = +$num_float;
    my $num_double_plus = +$num_double;
    
    if ($num_byte_plus == 1) {
      if ($num_short_plus == 1) {
        if ($num_int_plus == 1) {
          if ($num_long_plus == 1L) {
            if ($num_float_plus == 1f) {
              if ($num_double_plus == 1d) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  # Complement
  sub complement : int () {
    my $num_byte = (byte)0xF0;
    my $num_short = (short)0xFFF0;
    my $num_int = 0xFFFFFFF0;
    my $num_long = 0xFFFFFFFFFFFFFFF0L;
    
    my $num_byte_complement : int = ~$num_byte;
    my $num_short_complement : int = ~$num_short;
    my $num_int_complement = ~$num_int;
    my $num_long_complement = ~$num_long;
    
    if ($num_byte_complement == (byte)0xF) {
      if ($num_short_complement == (short)0xF) {
        if ($num_int_complement == 0xF) {
          if ($num_long_complement == 0xFL) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

  # Add
  sub add : int () {
    # int
    my $int_success = 0;
    {
      my $value1 : int = 1 + 2;
      my $value2 : int = (byte)1 + 3;
      my $value3 : int = 1 + (byte)4;
      my $value4 : int = (short)1 + 5;
      my $value5 : int = 1 + (short)6;
      my $value6 : int = (byte)1 + (byte)7;
      my $value7 : int = (short)1 + (short)8;
      my $value8 : int = (byte)1 + (short)9;
      if ($value1 == 3) {
        if ($value2 == 4) {
          if ($value3 == 5) {
            if ($value4 == 6) {
              if ($value5 == 7) {
                if ($value6 == 8) {
                  if ($value7 == 9) {
                    if ($value8 == 10) {
                      $int_success = 1;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # float
    my $float_success = 0;
    {
      my $value1 : float = 0.25f + 0.5f;
      my $value2 : float = (byte)2 + 0.5f;
      my $value3 : float = 0.5f + (byte)2;
      my $value4 : float = (short)2 + 0.5f;
      my $value5 : float = 0.5f + (short)2;
      my $value6 : float = 2 + 0.5f;
      my $value7 : float = 0.5f + 2;
      if ($value1 == 0.75f) {
        if ($value2 == 2.5f) {
          if ($value3 == 2.5f) {
            if ($value4 == 2.5f) {
              if ($value5 == 2.5f) {
                if ($value6 == 2.5f) {
                  if ($value7 == 2.5f) {
                    $float_success = 1;
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # double
    my $double_success = 0;
    {
      my $value1 : double = (byte)2 + 0.5;
      my $value2 : double = 0.5 + (byte)2;
      my $value3 : double = (short)2 + 0.5;
      my $value4 : double = 0.5 + (short)2;
      my $value5 : double = 2 + 0.5;
      my $value6 : double = 0.5 + 2;
      my $value7 : double = 0.5 + 0.25;
      my $value8 : double = 0.5 + 0.25f;
      my $value9 : double = 0.25f + 0.5;
      if ($value1 == 2.5) {
        if ($value2 == 2.5) {
          if ($value3 == 2.5) {
            if ($value4 == 2.5) {
              if ($value5 == 2.5) {
                if ($value6 == 2.5) {
                  if ($value7 == 0.75) {
                    if ($value8 == 0.75) {
                      if ($value9 == 0.75) {
                        $double_success = 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    if ($int_success && $float_success && $double_success) {
      return 1;
    }

    return 0;
  }

  # Add
  sub add_int_max : int () {
    return (int)2147483646 + (int)1;
  }
  
  sub add_int_min : int () {
    return (int)-2147483648 + (int)1;
  }
  
  sub add_int_overflow : int () {
    return (int)2147483647 + (int)1;
  }

  sub add_long_max : long () {
    return (long)9223372036854775806L + (long)1;
  }
  
  sub add_long_min : long () {
    return (long)-9223372036854775808L + (long)1;
  }
  
  sub add_long_overflow : long () {
    return (long)9223372036854775807L + (long)1;
  }

  # Subtract
  sub subtract : int () {
    my $value1 : int = 1 - 2;
    my $value2 : int = (byte)1 - 3;
    my $value3 : int = 1 - (byte)4;
    my $value4 : int = (short)1 - 5;
    my $value5 : int = 1 - (short)6;
    my $value6 : int = (byte)1 - (byte)7;
    my $value7 : int = (short)1 - (short)8;
    my $value8 : int = (byte)1 - (short)9;

    if ($value1 == -1) {
      if ($value2 == -2) {
        if ($value3 == -3) {
          if ($value4 == -4) {
            if ($value5 == -5) {
              if ($value6 == -6) {
                if ($value7 == -7) {
                  if ($value8 == -8) {
                    return 1;
                  }
                }
              }
            }
          }
        }
      }
    }

    return 0;
  }

  # Subtract
  sub subtract_int_max : int () {
    return (int)2147483647 - (int)1;
  }
  
  sub subtract_int_min : int () {
    return (int)-2147483647 - (int)1;
  }
  
  sub subtract_int_underflow : int () {
    return (int)-2147483648 - (int)1;
  }

  sub subtract_long_max : long () {
    return (long)9223372036854775807L - (long)1;
  }
  
  sub subtract_long_min : long () {
    return (long)-9223372036854775807L - (long)1;
  }
  
  sub subtract_long_underflow : long () {
    return (long)-9223372036854775808L - (long)1;
  }

  # Multiply
  sub multiply : int () {
    # int
    my $int_success = 0;
    {
      my $value1 : int = -2 * 2;
      my $value2 : int = (byte)-2 * 3;
      my $value3 : int = -2 * (byte)4;
      my $value4 : int = (short)-2 * 5;
      my $value5 : int = -2 * (short)6;
      my $value6 : int = (byte)-2 * (byte)7;
      my $value7 : int = (short)-2 * (short)8;
      my $value8 : int = (byte)-2 * (short)9;
      if ($value1 == -4) {
        if ($value2 == -6) {
          if ($value3 == -8) {
            if ($value4 == -10) {
              if ($value5 == -12) {
                if ($value6 == -14) {
                  if ($value7 == -16) {
                    if ($value8 == -18) {
                      $int_success = 1;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # float
    my $float_success = 0;
    {
      my $value1 : float = 0.25f * 0.5f;
      my $value2 : float = (byte)2 * 0.5f;
      my $value3 : float = 0.5f * (byte)2;
      my $value4 : float = (short)2 * 0.5f;
      my $value5 : float = 0.5f * (short)2;
      my $value6 : float = 2 * 0.5f;
      my $value7 : float = 0.5f * 2;
      if ($value1 == 0.125f) {
        if ($value2 == 1.0f) {
          if ($value3 == 1.0f) {
            if ($value4 == 1.0f) {
              if ($value5 == 1.0f) {
                if ($value6 == 1.0f) {
                  if ($value7 == 1.0f) {
                    $float_success = 1;
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # double
    my $double_success = 0;
    {
      my $value1 : double = (byte)2 * 0.5;
      my $value2 : double = 0.5 * (byte)2;
      my $value3 : double = (short)2 * 0.5;
      my $value4 : double = 0.5 * (short)2;
      my $value5 : double = 2 * 0.5;
      my $value6 : double = 0.5 * 2;
      my $value7 : double = 0.5 * 0.25;
      my $value8 : double = 0.5 * 0.25f;
      my $value9 : double = 0.25f * 0.5;
      if ($value1 == 1.0) {
        if ($value2 == 1.0) {
          if ($value3 == 1.0) {
            if ($value4 == 1.0) {
              if ($value5 == 1.0) {
                if ($value6 == 1.0) {
                  if ($value7 == 0.125) {
                    if ($value8 == 0.125) {
                      if ($value9 == 0.125) {
                        $double_success = 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    if ($int_success && $float_success && $double_success) {
      return 1;
    }

    return 0;
  }
  
  # Multiply
  sub multiply_int_plus : int () {
    return (int)536870912 * (int)2;
  }
  
  sub multiply_int_minus : int () {
    return (int)536870912 * (int)-2;
  }
  
  sub multiply_int_overflow : int () {
    return (int)1073741824 * (int)2;
  }
  
  sub multiply_long_plus : long () {
    return (long)2305843009213693952L * (long)2L;
  }
  
  sub multiply_long_minus : long () {
    return (long)2305843009213693952L * (long)-2L;
  }
  
  sub multiply_long_overflow : long () {
    return (long)4611686018427387904L * (long)2L;
  }
  
  # SPVM Functions
  sub spvm_new_byte_array_string : int ($values : byte[]) {
    
    if ((int)$values->[0] == (int)(byte)0xE3) {
      if ((int)$values->[1] == (int)(byte)0x81) {
        if ((int)$values->[2] == (int)(byte)0x82) {
          if (@$values == 3) {
            return 1;
          }
        }
      }
    }
    
    return 0;
  }

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

  sub spvm_new_byte_array_data_pack : int ($values : byte[]) {
    
    if ($values->[0] == 97) {
      if ($values->[1] == 98) {
        if ($values->[2] == Std::TypeUtil->BYTE_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_short_array_data_pack : int ($values : short[]) {
    
    if ((int)$values->[0] == (int)(short)97) {
      if ((int)$values->[1] == (int)(short)98) {
        if ((int)$values->[2] == (int)(short)Std::TypeUtil->SHORT_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  sub spvm_new_int_array_data_pack : int ($values : int[]) {
    
    if ($values->[0] == (int)97) {
      if ($values->[1] == (int)98) {
        if ($values->[2] == (int)Std::TypeUtil->INT_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_long_array_data_pack : int ($values : long[]) {
    
    if ($values->[0] == (long)97) {
      if ($values->[1] == (long)98) {
        if ($values->[2] == (long)Std::TypeUtil->LONG_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_float_array_data_pack : int ($values : float[]) {
    
    if ($values->[0] == (float)97) {
      if ($values->[1] == (float)98) {
        if ($values->[2] == (float)FLOAT_PRECICE()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  sub spvm_new_double_array_data_pack : int ($values : double[]) {
    
    if ($values->[0] == (double)97) {
      if ($values->[1] == (double)98) {
        if ($values->[2] == (double)DOUBLE_PRECICE()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  # byte array argument
  sub call_sub_byte_array : byte ($nums : byte[]) {
    
    my $total = (byte)0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = (byte)((int)$total + (int)$nums->[$i]);
    }
    
    return $total;
  }
  
  # short array argument
  sub call_sub_short_array : short ($nums : short[]) {
    
    my $total = (short)0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = (short)((int)$total + (int)$nums->[$i]);
    }
    
    return $total;
  }
  
  # int array argument
  sub call_sub_int_array : int ($nums : int[]) {
    
    my $total = 0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }
    
    return $total;
  }

  # long array argument
  sub call_sub_long_array : long ($nums : long[]) {
    
    my $total = (long)0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }
    
    return $total;
  }

  # float array argument
  sub call_sub_float_array : float ($nums : float[]) {
    
    my $total = (float)0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }
    
    return $total;
  }

  # double array argument
  sub call_sub_double_array : double ($nums : double[]) {
    
    my $total = (double)0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }
    
    return $total;
  }

  # constant int
  sub load_constant_int_min : int () {
   # LOAD_CONSTANT
    return -2147483647;
  }
  sub load_constant_int_m32769 : int () {
    # LOAD_CONSTANT
    return -32769;
  }
  sub load_constant_int_m32768 : int () {
    # PUSH_SHORT_TO_INT
    return -32768;
  }
  sub load_constant_int_m129 : int () {
    # PUSH_SHORT_TO_INT
    return -129;
  }
  sub load_constant_int_m128 : int () {
    # PUSH_BYTE_TO_INT
    return -128;
  }
  sub load_constant_int_m2 : int () {
    # PUSH_BYTE_TO_INT
    return -2;
  }
  sub load_constant_int_m1 : int () {
    # CONSTANT_INT_M1
    return -1;
  }
  sub load_constant_int_0 : int () {
    # CONSTANT_INT_0
    return 0;
  }
  sub load_constant_int_1 : int () {
    # CONSTANT_INT_1
    return 1;
  }
  sub load_constant_int_2 : int () {
    # CONSTANT_INT_2
    return 2;
  }
  sub load_constant_int_3 : int () {
    # CONSTANT_INT_3
    return 3;
  }
  sub load_constant_int_4 : int () {
    # CONSTANT_INT_4
    return 4;
  }
  sub load_constant_int_5 : int () {
    # CONSTANT_INT_5
    return 5;
  }
  sub load_constant_int_6 : int () {
    # PUSH_BYTE_TO_INT
    return 6;
  }
  sub load_constant_int_127 : int () {
    # PUSH_BYTE_TO_INT
    return 127;
  }
  sub load_constant_int_128 : int () {
    # PUSH_SHORT_TO_INT
    return 128;
  }
  sub load_constant_int_32767 : int () {
    # PUSH_SHORT_TO_INT
    return 32767;
  }
  sub load_constant_int_32768 : int () {
    # LOAD_CONSTANT
    return 32768;
  }
  sub load_constant_int_max : int () {
    # LOAD_CONSTANT
    return 2147483647;
  }

  # constant long
  sub load_constant_long_min : long () {
   # LOAD_CONSTANT
    return -9223372036854775808L;
  }
  sub load_constant_long_m32769 : long () {
    # LOAD_CONSTANT
    return -32769L;
  }
  sub load_constant_long_m32768 : long () {
    # PUSH_SHORT_TO_LONG
    return -32768L;
  }
  sub load_constant_long_m129 : long () {
    # PUSH_SHORT_TO_LONG
    return -129L;
  }
  sub load_constant_long_m128 : long () {
    # PUSH_BYTE_TO_LONG
    return -128L;
  }
  sub load_constant_long_m2 : long () {
    # PUSH_BYTE_TO_LONG
    return -2L;
  }
  sub load_constant_long_m1 : long () {
    # CONSTANT_LONG_M1
    return -1L;
  }
  sub load_constant_long_0 : long () {
    # CONSTANT_LONG_0
    return 0L;
  }
  sub load_constant_long_1 : long () {
    # CONSTANT_LONG_1
    return 1L;
  }
  sub load_constant_long_2 : long () {
    # CONSTANT_LONG_2
    return 2L;
  }
  sub load_constant_long_3 : long () {
    # CONSTANT_LONG_3
    return 3L;
  }
  sub load_constant_long_4 : long () {
    # CONSTANT_LONG_4
    return 4L;
  }
  sub load_constant_long_5 : long () {
    # CONSTANT_LONG_5
    return 5L;
  }
  sub load_constant_long_6 : long () {
    # PUSH_BYTE_TO_LONG
    return 6L;
  }
  sub load_constant_long_127 : long () {
    # PUSH_BYTE_TO_LONG
    return 127L;
  }
  sub load_constant_long_128 : long () {
    # PUSH_SHORT_TO_LONG
    return 128L;
  }
  sub load_constant_long_32767 : long () {
    # PUSH_SHORT_TO_LONG
    return 32767L;
  }
  sub load_constant_long_32768 : long () {
    # LOAD_CONSTANT2
    return 32768L;
  }
  sub load_constant_long_max : long () {
    # LOAD_CONSTANT2
    return 9223372036854775807L;
  }
  
  # constant float
  sub load_constant_float_0 : float () {
    # CONSTANT_FLOAT_0
    return 0.0f;
  }
  sub load_constant_float_1 : float () {
    # CONSTANT_FLOAT_1
    return 1.0f;
  }
  sub load_constant_float_0_5 : float () {
    # LOAD_CONSTANT
    return 0.5f;
  }
  sub load_constant_float_exponent_E_plus : float () {
    return 0.5E+3f;
  }
  sub load_constant_float_exponent_e_plus : float () {
    return 0.5e3f;
  }
  sub load_constant_float_exponent_E_minus : float () {
    return 62.5E-3f;
  }
  sub load_constant_float_exponent_e_minus : float () {
    return 62.5e-3f;
  }

  sub load_constant_double_exponent_E_plus : double () {
    return 0.5E+3;
  }
  sub load_constant_double_exponent_e_plus : double () {
    return 0.5e3;
  }
  sub load_constant_double_exponent_E_minus : double () {
    return 62.5E-3;
  }
  sub load_constant_double_exponent_e_minus : double () {
    return 62.5e-3;
  }
  
  # constant double
  sub load_constant_double_0 : double () {
    # CONSTANT_DOUBLE_0
    return 0.0;
  }
  sub load_constant_double_1 : double () {
    # CONSTANT_DOUBLE_1
    return 1.0;
  }
  sub load_constant_double_0_5 : double () {
    # LOAD_CONSTANT2
    return 0.5;
  }
  
  # call_sub arguments
  sub call_sub_args_byte : int ($var1 : byte, $var2 : byte, $var3 : byte) {
    if ($var1 == 0) {
      if ($var2 == 127) {
        if ($var3 == -128) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  sub call_sub_args_short : int ($var1 : short, $var2 : short, $var3 : short) {
    if ((int)$var1 == (int)(short)0) {
      if ((int)$var2 == (int)(short)32767) {
        if ((int)$var3 == (int)(short)-32768) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  sub call_sub_args_int : int ($var1 : int, $var2 : int, $var3 : int) {
    if ($var1 == 0) {
      if ($var2 == 2147483647) {
        if ($var3 == -2147483648) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  sub call_sub_args_long : int ($var1 : long, $var2 : long, $var3 : long) {
    if ($var1 == 0L) {
      if ($var2 == 9223372036854775807L) {
        if ($var3 == -9223372036854775808L) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  sub bit_and : int () {
    # byte
    my $byte_success = 0;
    {
      my $value1 : int = (byte)0xFF & (byte)0x0F;
      if ($value1 & 0xFF == 0x0F) {
        $byte_success = 1;
      }
    }

    # short
    my $short_success = 0;
    {
      my $value1 : int = (short)0xFF00 & (short)0xF0F0;
      if ($value1 & 0xFFFF == 0xF000) {
        $short_success = 1;
      }
    }
    
    # int
    my $int_success = 0;
    {
      my $value1 = 0xFF00 & 0xF0F0;
      if ($value1 == 0xF000) {
        $int_success = 1;
      }
    }
    
    # long
    my $long_success = 0;
    {
      my $value1 = 0xFF00FF00L & 0xF0F0F0F0L;
      if ($value1 == 0xF000F000L) {
        $long_success = 1;
      }
    }
    
    if ($byte_success && $short_success && $int_success && $long_success) {
      return 1;
    }
    
    return 0;
  }

  sub bit_or : int () {
    # byte
    my $byte_success = 0;
    {
      my $value1 : int = (byte)0xF0 | (byte)0xFF;
      if ($value1 & 0xFF == 0xFF) {
        $byte_success = 1;
      }
    }

    # short
    my $short_success = 0;
    {
      my $value1 : int = (short)0xFF00 | (short)0xF0F0;
      if ($value1 & 0xFFFF == 0xFFF0) {
        $short_success = 1;
      }
    }

    # int
    my $int_success = 0;
    {
      my $value1 = 0xFF00 | 0xF0F0;
      if ($value1 == 0xFFF0) {
        $int_success = 1;
      }
    }
    
    # long
    my $long_success = 0;
    {
      my $value2 = 0xFF00FF00L | 0xF0F0F0F0L;
      if ($value2 == 0xFFF0FFF0L) {
        $long_success = 1;
      }
    }

    if ($byte_success && $short_success && $int_success && $long_success) {
      return 1;
    }
    
    return 0;
  }

  sub bit_xor : int () {
    # byte
    my $byte_success = 0;
    {
      my $value1 : int = (byte)0xF0 ^ (byte)0x0F;
      if ($value1 & 0xFF == 0xFF) {
        $byte_success = 1;
      }
    }
    
    # short
    my $short_success = 0;
    {
      my $value1 : int = (short)0xFF00 ^ (short)0xF0F0;
      if ($value1 & 0xFFFF == 0x0FF0) {
        $short_success = 1;
      }
    }
    
    # int
    my $int_success = 0;
    {
      my $value1 = 0xFF00 ^ 0xF0F0;
      if ($value1 == 0x0FF0) {
        $int_success = 1;
      }
    }
    
    # long
    my $long_success = 0;
    {
      my $value1 = 0xFF00FF00L ^ 0xF0F0F0F0L;
      if ($value1 == 0x0FF00FF0L) {
        $long_success = 1;
      }
    }
    
    if ($byte_success && $short_success && $int_success && $long_success) {
      return 1;
    }
    
    return 0;
  }

  sub bit_shift_right_logical_int : int () {
    # 11000000 00000000 00000000 00000001 >>> 2
    my $value = 0xC0000001 >>> 2;
    
    # 00110000 00000000 00000000 00000000
    if ($value == 0x30000000) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub bit_shift_right_logical_long : int () {
    # 11000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 >>> 2
    my $value = 0xC000000000000001L >>> 2;
    
    # 00110000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    if ($value == 0x3000000000000000L) {
      return 1;
    }
    else {
      return 0;
    }
  }

  sub bit_shift_right_int : int () {
    # 11000000 00000000 00000000 00000001 >> 2
    my $value = 0xC0000001 >> 2;
    
    # 11110000 00000000 00000000 00000000
    if ($value == 0xF0000000) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub bit_shift_right_long : int () {
    # 11000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 >> 2
    my $value = 0xC000000000000001L >> 2;
    
    # 11110000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    if ($value == 0xF000000000000000L) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub literal_character : int () {
    my $value = 'a';
    
    return 1;
  }
  
  sub number_literal_specifier : int () {
    my $value1 = 255f;
    my $value2 = 255d;
    my $value3 = 255L;
    my $value4 = (byte)-128;
    my $value5 = (short)-32768;
    my $value6 = (byte)127;
    my $value7 = (short)-128;
    
    if ($value1 == (float)255) {
      if ($value2 == (double)255) {
        if ($value3 == (long)255) {
          if ($value4 == -1) {
            if ($value5 == -1) {
              if ($value6 == 127) {
                if ($value7 == 32767) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
  
  sub number_literal_underline : int () {
    my $value = 123_123;
    
    if ($value == 123123) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub number_literal_hex_specifier : int () {
    my $value3 = 0xFFL;
    my $value4 = (byte)0xFF;
    my $value5 = (short)0xFFFF;
    my $value6 = (byte)0x7F;
    my $value7 = (short)0x7FFF;
    
    if ($value3 == (long)255) {
      if ($value4 == -1) {
        if ($value5 == -1) {
          if ($value6 == 127) {
            if ($value7 == 32767) {
              return 1;
            }
          }
        }
      }
    }
    
    return 0;
  }
  sub number_literal_hex_all_number : int () {
    my $value1 = 0x01234567;
    my $value2 = 0x00ABCDEF;
    my $value3 = 0x00abcdef;
    
    if ($value1 == 19088743) {
      if ($value2 == 11259375) {
        if ($value3 == 11259375) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub number_literal_underline_hex : int () {
    my $value = 0xFF_FF;
    
    if ($value == 0xFFFF) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub number_literal_hex_int : int () {
    my $value = 0xFF;
    
    if ($value == 255) {
      return 1;
    }
    else {
      return 0;
    }
  }
  sub number_literal_hex_int_max : int () {
    # 11111111 11111111 11111111 11111111
    my $value = 0xFFFFFFFF;
    
    if ($value == -1) {
      return 1;
    }
    else {
      return 0;
    }
  }
  sub number_literal_hex_long_max : int () {
    # 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
    my $value = 0xFFFFFFFFFFFFFFFFL;
    
    if ($value == -1L) {
      return 1;
    }
    else {
      return 0;
    }
  }

  sub number_literal_octal_specifier : int () {
    my $value3 = 0377L;
    my $value4 = (byte)0377;
    my $value5 = (short)0177777;
    my $value6 = (byte)0177;
    my $value7 = (short)077777;
    
    if ($value3 == (long)255) {
      if ($value4 == -1) {
        if ($value5 == -1) {
          if ($value6 == 127) {
            if ($value7 == 32767) {
              return 1;
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub number_literal_octal_all_number : int () {
    my $value1 = 0110642547;
    
    if ($value1 == 19088743) {
      return 1;
    }
    
    return 0;
  }

  sub number_literal_binary_specifier : int () {
    my $value3 = 0b11111111L;
    my $value4 = (byte)0b11111111;
    my $value5 = (short)0b1111111111111111;
    my $value6 = (byte)0b1111111;
    my $value7 = (short)0b111111111111111;
    
    if ($value3 == (long)255) {
      if ($value4 == -1) {
        if ($value5 == -1) {
          if ($value6 == 127) {
            if ($value7 == 32767) {
              return 1;
            }
          }
        }
      }
    }
    
    return 0;
  }
  sub number_literal_binary_all_number : int () {
    my $value1 = 0b1001000110100010101100111;
    
    if ($value1 == 19088743) {
      return 1;
    }
    
    return 0;
  }

  sub number_literal_underline_binary : int () {
    my $value = 0b11111111_11111111;
    
    if ($value == 0b1111111111111111) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub number_literal_binary_int : int () {
    my $value = 0b11111111;
    
    if ($value == 255) {
      return 1;
    }
    else {
      return 0;
    }
  }
  sub number_literal_binary_int_max : int () {
    # 11111111 11111111 11111111 11111111
    my $value = 0b11111111111111111111111111111111;
    
    if ($value == -1) {
      return 1;
    }
    else {
      return 0;
    }
  }
  sub number_literal_binary_long_max : int () {
    # 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
    my $value = 0b1111111111111111111111111111111111111111111111111111111111111111L;
    
    if ($value == -1L) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub number_literal_underline_octal : int () {
    my $value = 0177_777;
    
    if ($value == 0177777) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub number_literal_octal_int : int () {
    my $value = 0377;
    
    if ($value == 255) {
      return 1;
    }
    else {
      return 0;
    }
  }
  sub number_literal_octal_int_max : int () {
    # 11111111 11111111 11111111 11111111
    my $value = 037777777777;
    
    if ($value == -1) {
      return 1;
    }
    else {
      return 0;
    }
  }
  sub number_literal_octal_long_max : int () {
    # 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
    my $value = 01777777777777777777777L;
    
    if ($value == -1L) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  # Bit shift left
  sub bit_shift_left_int : int () {
    
    # 00000011 00000000 00000000 00000000 << 2
    my $value = 0x30000000 << 2;
    
    # 00001100 00000000 00000000 00000000
    if ($value == 0xC0000000) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub bit_shift_left_int_max : int () {
    
    # 01000000 00000000 00000000 00000000 << 1
    my $value = 0x40000000 << 1;
    
    # 10000000 00000000 00000000 00000000
    if ($value == 0x80000000) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub bit_shift_left_int_overflow : int () {
    
    # 10000000 00000000 00000000 00000000 << 1
    my $value = 0x80000000 << 1;
    
    # 00000000 00000000 00000000 00000000
    if ($value == 0) {
      return 1;
    }
    else {
      return 0;
    }
  }

  sub bit_shift_left_long : int () {
    
    # 00000011 00000000 00000000 00000000 00000000 00000000 00000000 00000000 << 2
    my $value = 0x3000000000000000L << 2;
    
    # 00001100 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
    if ($value == 0xC000000000000000L) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub bit_shift_left_long_max : int () {
    
    # 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  << 1
    my $value = 0x4000000000000000L << 1;
    
    # 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
    if ($value == 0x8000000000000000L) {
      return 1;
    }
    else {
      return 0;
    }
  }
  
  sub bit_shift_left_long_overflow : int () {
    
    # 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  << 1
    my $value = 0x8000000000000000L << 1;
    
    # 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
    if ($value == 0L) {
      return 1;
    }
    else {
      return 0;
    }
  }

  # Array length
  sub get_array_length_at : int () {
    
    my $nums = new int[3];
    my $len = @$nums;
    if ($len == 3) {
      return 1;
    }
    
    return 0;
  }
  sub get_array_length_len : int () {
    
    my $nums = new int[3];
    my $len = len $nums;
    if ($len == 3) {
      return 1;
    }
    
    return 0;
  }

  sub get_array_length_undef : int () {
    
    my $nums : int[] = undef;

    eval {
      @$nums;
    };
    
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub array : int () {
    {
      my $nums : int[][] = new int[][3];
    }
    
    my $nums = new int[(byte)3];
    $nums->[2] = 4;
    if ($nums->[(byte)2] == 4) {
      return 1;
    }
  }
  sub array_set_and_get_array_element_first : int () {
    
    my $nums = new int[3];
    $nums->[0] = 345;

    return $nums->[0];
  }

  sub array_set_and_get_array_element_last : int () {
    
    my $nums = new int[3];
    $nums->[2] = 298;

    return $nums->[2];
  }

  sub array_culcurate_sum_by_for : int () {
    
    my $nums = new int[3];
    $nums->[0] = 1;
    $nums->[1] = 2;
    $nums->[2] = 3;
    
    my $total = 0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }

    return $total;
  }
  
  # Sum
  sub sum_byte : byte ($a : byte, $b :byte,) {
    
    my $total = (byte)((int)$a + (int)$b);
    
    return $total;
  }

  sub sum_short : short ($a : short, $b :short) {
    
    my $total = (short)((int)$a + (int)$b);
    
    return $total;
  }

  sub sum_int : int ($a : int, $b :int) {
    
    my $total = $a + $b;
    
    return $total;
  }

  sub sum_long : long ($a : long, $b :long) {
    
    my $total = $a + $b;
    
    return $total;
  }

  sub sum_float : float ($a : float, $b :float) {
    
    my $total = $a + $b;
    
    return $total;
  }

  sub sum_double : double ($a : double, $b :double) {
    
    my $total = $a + $b;
    
    return $total;
  }
  
  # For
  sub for_basic : int () {
  
    my $success_basic = 0;
    {
      my $total = 0;
      for (my $i = 1; $i <= 3; $i++) {
        $total = $total + $i;
      }
      
      if ($total == 6) {
        $success_basic = 1;
      }
    }
    
    my $success_last = 0;
    {
      my $total = 0;
      for (my $i = 0; $i < 10; $i++) {
        if ($i == 5) {
          last;
        }
        $total = $total + $i;
      }
      
      if ($total == 10) {
        $success_last = 1;
      }
    }

    my $success_next = 0;
    {
      my $total = 0;
      for (my $i = 0; $i < 10; $i++) {
        if ($i == 5) {
          next;
        }
        $total = $total + $i;
      }
      
      if ($total == 40) {
        $success_next = 1;
      }
    }

    my $success_while = 0;
    {
      my $total = 0;
      my $i = 0;
      while ($i <= 3) {
        $total = $total + $i;
        $i++;
      }
      
      if ($total == 6) {
        $success_while = 1;
      }
    }
    
    # Check also object count
    my $success_last_object = 0;
    {
      my $total = 0;
      for (my $i = 0; $i < 10; $i++) {
        my $minimal = TestCase::Minimal->new();
        if ($i == 5) {
          last;
        }
        $total = $total + $i;
      }
      
      if ($total == 10) {
        $success_last_object = 1;
      }
    }

    # Check also object count
    my $success_next_object = 0;
    {
      my $total = 0;
      for (my $i = 0; $i < 10; $i++) {
        my $minimal = TestCase::Minimal->new();
        if ($i == 5) {
          next;
        }
        $total = $total + $i;
      }
      
      if ($total == 40) {
        $success_next_object = 1;
      }
    }
    
    if ($success_basic) {
      if ($success_last) {
        if ($success_next) {
          if ($success_while) {
            if ($success_last_object) {
              if ($success_next_object) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
}