class TestCase::Operator::MethodCall {
  interface TestCase::Interface::Type;
  
  use TestCase::Simple;
  use TestCase::SimpleChild;
  use TestCase::Minimal;
  use TestCase::Point_3b;
  use TestCase::Point_3s;
  use TestCase::Point_3i;
  use TestCase::Point_3l;
  use TestCase::Point_3f;
  use TestCase::Point_3d;
  use Comparator;
  use TestCase::Simple as TS;
  use Complex_2d;
  use Fn;
  use Array;
  use Point;
  use TestCase::Interface::OptionalArgument;
  use TestCase::SimpleChildOfChild;
  
  # Use keyword name as method name
  static method int : int () {
    
    return 5;
  }
  method if : int () {
    
    return 3;
  }
  static method _under_score : int () {
    return 4;
  }

  static method call_keyword_name_method : int () {
    
    # Call a static method with parenthes
    {
      my $num = TestCase::Operator::MethodCall->int();
      unless ($num == 5) {
        return 0;
      }
    }
    
    # Call a static method without parenthes
    {
      my $num = TestCase::Operator::MethodCall->int;
      unless ($num == 5) {
        return 0;
      }
    }
    
    # Call a static method with parenthes and current class
    {
      my $num = &int();
      unless ($num == 5) {
        return 0;
      }
    }
    
    # Call a static method without parenthes and current class
    {
      my $num = &int;
      unless ($num == 5) {
        return 0;
      }
    }
    
    # Call a instance method with parenthes
    {
      my $method = new TestCase::Operator::MethodCall;
      my $num = $method->if();
      unless ($num == 3) {
        return 0;
      }
    }

    # Call a instance method without parenthes
    {
      my $method = new TestCase::Operator::MethodCall;
      my $num = $method->if;
      unless ($num == 3) {
        return 0;
      }
    }

    # Call a static method with current class that starts under score.
    {
      my $num = &_under_score();
      unless ($num == 4) {
        return 0;
      }
    }
    
    return 1;
  }

  static method test_import_method : int () {
    unless (TS->import_method1() == 1) {
      return 0;
    }
    
    unless (TS->import_method2() == 2) {
      return 0;
    }
    
    return 1;
  }
  
  static method already_exists_method_no_arg : int () {
    return 3;
  }

  static method already_exists_method : int ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }

  static method test_return_mulnum_automatical_numeric_convertion_widening : double () {
    
    return 2;
  }

  static method test_return_mulnum_automatical_numeric_convertion_narrowing_byte : byte () {
    
    return 127;
  }

  static method test_return_mulnum_automatical_numeric_convertion_narrowing_short : short () {
    
    return 32767;
  }
  
  static method return_mulnum_automatical_numeric_convertion : int () {
    {
      my $num : double = &test_return_mulnum_automatical_numeric_convertion_widening();
      unless ($num == 2.0) {
        return 0;
      }
    }
    
    {
      my $num : byte = &test_return_mulnum_automatical_numeric_convertion_narrowing_byte();
      unless ($num == 127) {
        return 0;
      }
    }
    
    {
      my $num : short = &test_return_mulnum_automatical_numeric_convertion_narrowing_short();
      unless ($num == 32767) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method cb_obj_capture : int () {
    my $capture1 = 7;
    my $capture2 = 10;
    my $cb_obj = [has capture1 : int = $capture1, has capture2 : int = $capture2] method : int ($x1 : object, $x2 : object) {
      my $capture1 = $self->{capture1};
      my $capture2 = $self->{capture2};
      
      unless ($capture1 == 7) {
        return 0;
      }
      
      unless ($capture2 == 10) {
        return 0;
      }
      
      unless ($self->{capture1} == 7) {
        return 0;
      }
      
      $self->{capture1} = 5;
      
      unless ($self->{capture1} == 5) {
        return 0;
      }
      
      return 1;
    };
    
    return $cb_obj->(undef, undef);
  }
  
  static method cb_obj_call_cb_obj : int () {
    my $cb_obj = method : int ($x1 : int, $x2 : int) {
      return $x1 + $x2;
    };
    
    my $total = $cb_obj->(1, 3);
    
    unless ($total == 4) {
      return 0;
    }
    
    return 1;
  }

  static method cb_obj_call_cb_obj_from_callback : int () {
    my $cb_obj = method : int ($x1 : object, $x2 : object) {
      my $x1_num = (int)$x1;
      my $x2_num = (int)$x2;
      return $x1_num + $x2_num;
    };
    
    my $comparator : Comparator = $cb_obj;
    
    my $total = $comparator->(2, 3);
    
    unless ($total == 5) {
      return 0;
    }
    
    return 1;
  }
  
  static method return_mulnum_byte_method : TestCase::Point_3b () {
    my $value : TestCase::Point_3b;
    $value->{x} = Fn->INT8_MIN;
    $value->{y} = 1;
    $value->{z} = 2;
    
    return $value;
  }
  
  static method return_mulnum_byte : int () {
    my $value : TestCase::Point_3b = TestCase::Operator::MethodCall->return_mulnum_byte_method();
    
    if ($value->{x} == Fn->INT8_MIN) {
      if ($value->{y} == 1) {
        if ($value->{z} == 2) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method return_mulnum_short_method : TestCase::Point_3s () {
    my $value : TestCase::Point_3s;
    $value->{x} = Fn->INT16_MIN;
    $value->{y} = 1;
    $value->{z} = 2;
    
    return $value;
  }
  
  static method return_mulnum_short : int () {
    my $value : TestCase::Point_3s = TestCase::Operator::MethodCall->return_mulnum_short_method();
    
    if ($value->{x} == Fn->INT16_MIN) {
      if ($value->{y} == 1) {
        if ($value->{z} == 2) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method return_mulnum_int_method : TestCase::Point_3i () {
    my $value : TestCase::Point_3i;
    $value->{x} = Fn->INT32_MIN;
    $value->{y} = 1;
    $value->{z} = 2;
    
    return $value;
  }
  
  static method return_mulnum_int : int () {
    my $value : TestCase::Point_3i = TestCase::Operator::MethodCall->return_mulnum_int_method();
    
    if ($value->{x} == Fn->INT32_MIN) {
      if ($value->{y} == 1) {
        if ($value->{z} == 2) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method return_mulnum_long_method : TestCase::Point_3l () {
    my $value : TestCase::Point_3l;
    $value->{x} = Fn->INT64_MIN;
    $value->{y} = 1;
    $value->{z} = 2;
    
    return $value;
  }
  
  static method return_mulnum_long : int () {
    my $value : TestCase::Point_3l = TestCase::Operator::MethodCall->return_mulnum_long_method();
    
    if ($value->{x} == Fn->INT64_MIN) {
      if ($value->{y} == 1) {
        if ($value->{z} == 2) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method return_mulnum_float_method : TestCase::Point_3f () {
    my $value : TestCase::Point_3f;
    $value->{x} = Fn->FLT_MIN;
    $value->{y} = 0.25f;
    $value->{z} = 0.5f;
    
    return $value;
  }
  
  static method return_mulnum_float : int () {
    my $value : TestCase::Point_3f = TestCase::Operator::MethodCall->return_mulnum_float_method();
    
    if ($value->{x} == Fn->FLT_MIN) {
      if ($value->{y} == 0.25f) {
        if ($value->{z} == 0.5f) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method return_mulnum_double_method : TestCase::Point_3d () {
    my $value : TestCase::Point_3d;
    $value->{x} = Fn->DBL_MIN;
    $value->{y} = 0.25;
    $value->{z} = 0.5;
    
    return $value;
  }
  
  static method return_mulnum_double : int () {
    my $value : TestCase::Point_3d = TestCase::Operator::MethodCall->return_mulnum_double_method();
    
    if ($value->{x} == Fn->DBL_MIN) {
      if ($value->{y} == 0.25) {
        if ($value->{z} == 0.5) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method method_push_arg_undef : TestCase::Minimal ($minimal : TestCase::Minimal) {
    return $minimal;
  }

  static method push_arg_undef : int () {
  
    my $minimal = TestCase::Operator::MethodCall->method_push_arg_undef(undef);
    
    if ($minimal == undef) {
      return 1;
    }
    
    return 0;
  }

  # Default return value empty
  static method default_return_mulnum_byte : int () {
    
    if (TestCase::Operator::MethodCall->default_return_mulnum_byte_method() == 0) {
      if (TestCase::Operator::MethodCall->default_return_mulnum_byte_method_empty() == 0) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_byte_method : byte () {
    1;
  }
  static method default_return_mulnum_byte_method_empty : byte () {
    
  }
  static method default_return_mulnum_short : int () {
    
    if ((int)TestCase::Operator::MethodCall->default_return_mulnum_short_method() == (int)(short)0) {
      if ((int)TestCase::Operator::MethodCall->default_return_mulnum_short_method_empty() == (int)(short)0) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_short_method : short () {
    1;
  }
  static method default_return_mulnum_short_method_empty : short () {
    
  }
  static method default_return_mulnum_int : int () {
    
    if (TestCase::Operator::MethodCall->default_return_mulnum_int_method() == (int)0) {
      if (TestCase::Operator::MethodCall->default_return_mulnum_int_method_empty() == (int)0) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_int_method : int () {
    1;
  }
  static method default_return_mulnum_int_method_empty : int () {
    
  }
  static method default_return_mulnum_long : int () {
    
    if (TestCase::Operator::MethodCall->default_return_mulnum_long_method() == (long)0) {
      if (TestCase::Operator::MethodCall->default_return_mulnum_long_method_empty() == (long)0) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_long_method : long () {
    1;
  }
  static method default_return_mulnum_long_method_empty : long () {
    
  }
  static method default_return_mulnum_float : int () {
    
    if (TestCase::Operator::MethodCall->default_return_mulnum_float_method() == (float)0) {
      if (TestCase::Operator::MethodCall->default_return_mulnum_float_method_empty() == (float)0) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_float_method : float () {
    1;
  }
  static method default_return_mulnum_float_method_empty : float () {
    
  }
  static method default_return_mulnum_double : int () {
    
    if (TestCase::Operator::MethodCall->default_return_mulnum_double_method() == (double)0) {
      if (TestCase::Operator::MethodCall->default_return_mulnum_double_method_empty() == (double)0) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_double_method : double () {
    1;
  }
  static method default_return_mulnum_double_method_empty : double () {
    
  }
  static method default_return_mulnum_object : int () {
    
    if (TestCase::Operator::MethodCall->default_return_mulnum_object_method() == undef) {
      if (TestCase::Operator::MethodCall->default_return_mulnum_object_method_empty() == undef) {
        return 1;
      }
    }
    
    return 0;
  }
  static method default_return_mulnum_object_method : TestCase::Minimal () {
    1;
  }
  static method default_return_mulnum_object_method_empty : TestCase::Minimal () {
    
  }
  
  # Call void function
  static method call_void_method : void ($nums : int[]) {
    $nums->[0] = 5;
  }
  static method call_void : int () {
    my $nums = [1];
    
    TestCase::Operator::MethodCall->call_void_method($nums);
    
    if ($nums->[0] == 5) {
      return 1;
    }
    return 0;
  }
  
  static method call_method_nest : int () {
    my $total = TestCase::Operator::MethodCall->call_method_nest_sum( TestCase::Operator::MethodCall->call_method_nest_sum(1, 2), TestCase::Operator::MethodCall->call_method_nest_sum(3, 4));
    
    if ($total == 10) {
      return 1;
    }
    
    return 0;
  }
  static method call_method_nest_sum : int ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }
  static method call_method_args_convertion_stab1 : double ($var1 : byte, $var2 : short, $var3 : int, $var4 : long, $var5 : float, $var6 : double) {
    return ($var1 + $var2 + $var3 + $var4 + $var5 + $var6);
  }
  
  static method call_method_args_convertion : int () {
    # Constant assignment
    my $success_constant_narrow = 0;
    {
      my $return_mulnum1 = TestCase::Operator::MethodCall->call_method_args_convertion_stab1(1, 2, 3, 2, 8, 16);
      if ($return_mulnum1 == 32) {
        $success_constant_narrow = 1;
      }
    }
    
    # Widning
    my $success_constant_wide = 0;
    {
      my $return_mulnum1 = TestCase::Operator::MethodCall->call_method_args_convertion_stab1((byte)1, (byte)2, (byte)3, (byte)2, (byte)8, (byte)16);
      
      if ($return_mulnum1 == 32) {
        $success_constant_wide = 1;
      }
    }
    
    if ($success_constant_narrow && $success_constant_wide) {
      return 1;
    }
    
    return 0;
  }

  # call_method arguments
  static method call_method_args_byte : int ($var1 : byte, $var2 : byte, $var3 : byte) {
    if ($var1 == 0) {
      if ($var2 == 127) {
        if ($var3 == -128) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  static method call_method_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;
  }
  static method call_method_args_int : int ($var1 : int, $var2 : int, $var3 : int) {
    if ($var1 == 0) {
      if ($var2 == 2147483647) {
        if ($var3 == -2147483648) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  
  static method call_method_args_long : int ($var1 : long, $var2 : long, $var3 : long) {
    if ($var1 == 0L) {
      if ($var2 == 9223372036854775807L) {
        if ($var3 == -9223372036854775808L) {
          return 1;
        }
      }
    }
    
    return 0;
  }
  # byte array argument
  static method call_method_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
  static method call_method_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
  static method call_method_int_array : int ($nums : int[]) {
    
    my $total = 0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }
    
    return $total;
  }

  # long array argument
  static method call_method_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
  static method call_method_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
  static method call_method_double_array : double ($nums : double[]) {
    
    my $total = (double)0;
    for (my $i = 0; $i < @$nums; $i++) {
      $total = $total + $nums->[$i];
    }
    
    return $total;
  }
  # call_method return value
  static method call_method_return_byte_array  : byte[] () {
    my $nums = new byte[3];
    
    $nums->[0] = (byte)1;
    $nums->[1] = (byte)2;
    $nums->[2] = (byte)3;
    
    return $nums;
  }
  static method call_method_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;
  }

  static method call_method_return_short_array : short[] () {
    my $nums = new short[3];
    
    $nums->[0] = (short)1;
    $nums->[1] = (short)2;
    $nums->[2] = (short)3;
    
    return $nums;
  }
  static method call_method_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;
  }

  static method call_method_return_int_array : int[] () {
    my $nums = new int[3];
    
    $nums->[0] = (int)1;
    $nums->[1] = (int)2;
    $nums->[2] = (int)3;
    
    return $nums;
  }
  static method call_method_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;
  }

  static method call_method_return_long_array : long[] () {
    my $nums = new long[3];
    
    $nums->[0] = (long)1;
    $nums->[1] = (long)2;
    $nums->[2] = (long)3;
    
    return $nums;
  }
  static method call_method_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;
  }

  static method call_method_return_float_array : float[] () {
    my $nums = new float[3];
    
    $nums->[0] = (float)1;
    $nums->[1] = (float)2;
    $nums->[2] = (float)3;
    
    return $nums;
  }
  static method call_method_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;
  }

  static method call_method_return_double_array : double[] () {
    my $nums = new double[3];
    
    $nums->[0] = (double)1;
    $nums->[1] = (double)2;
    $nums->[2] = (double)3;
    
    return $nums;
  }
  static method call_method_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;
  }
  static method call_method_assign : int () {
    my $m = TestCase::Minimal->new();
    $m = TestCase::Minimal->new();
  }
  
  static method call_method_undef : int ($value : TestCase::Minimal) {
    
    if ($value == undef) {
      return 1;
    }
    
    return 0;
  }

  static method call_method_last_camma : int () {
    
    my $total =  TestCase::Operator::MethodCall->sum_int(3, 4,);
    
    if ($total == 7) {
      return 1;
    }
    
    return 0;
  }
  static method sum_int : int ($a : int, $b :int) {
    
    my $total = $a + $b;
    
    return $total;
  }

  static method args_max_count : int ($x1 : int, $x2 : int, $x3 : int, $x4 : int, $x5 : int, $x6 : int, $x7 : int, $x8 : int, $x9 : int, $x10 : int, $x11 : int, $x12 : int, $x13 : int, $x14 : int, $x15 : int, $x16 : int, $x17 : int, $x18 : int, $x19 : int, $x20 : int, $x21 : int, $x22 : int, $x23 : int, $x24 : int, $x25 : int, $x26 : int, $x27 : int, $x28 : int, $x29 : int, $x30 : int, $x31 : int, $x32 : int, $x33 : int, $x34 : int, $x35 : int, $x36 : int, $x37 : int, $x38 : int, $x39 : int, $x40 : int, $x41 : int, $x42 : int, $x43 : int, $x44 : int, $x45 : int, $x46 : int, $x47 : int, $x48 : int, $x49 : int, $x50 : int, $x51 : int, $x52 : int, $x53 : int, $x54 : int, $x55 : int, $x56 : int, $x57 : int, $x58 : int, $x59 : int, $x60 : int, $x61 : int, $x62 : int, $x63 : int, $x64 : int, $x65 : int, $x66 : int, $x67 : int, $x68 : int, $x69 : int, $x70 : int, $x71 : int, $x72 : int, $x73 : int, $x74 : int, $x75 : int, $x76 : int, $x77 : int, $x78 : int, $x79 : int, $x80 : int, $x81 : int, $x82 : int, $x83 : int, $x84 : int, $x85 : int, $x86 : int, $x87 : int, $x88 : int, $x89 : int, $x90 : int, $x91 : int, $x92 : int, $x93 : int, $x94 : int, $x95 : int, $x96 : int, $x97 : int, $x98 : int, $x99 : int, $x100 : int, $x101 : int, $x102 : int, $x103 : int, $x104 : int, $x105 : int, $x106 : int, $x107 : int, $x108 : int, $x109 : int, $x110 : int, $x111 : int, $x112 : int, $x113 : int, $x114 : int, $x115 : int, $x116 : int, $x117 : int, $x118 : int, $x119 : int, $x120 : int, $x121 : int, $x122 : int, $x123 : int, $x124 : int, $x125 : int, $x126 : int, $x127 : int, $x128 : int, $x129 : int, $x130 : int, $x131 : int, $x132 : int, $x133 : int, $x134 : int, $x135 : int, $x136 : int, $x137 : int, $x138 : int, $x139 : int, $x140 : int, $x141 : int, $x142 : int, $x143 : int, $x144 : int, $x145 : int, $x146 : int, $x147 : int, $x148 : int, $x149 : int, $x150 : int, $x151 : int, $x152 : int, $x153 : int, $x154 : int, $x155 : int, $x156 : int, $x157 : int, $x158 : int, $x159 : int, $x160 : int, $x161 : int, $x162 : int, $x163 : int, $x164 : int, $x165 : int, $x166 : int, $x167 : int, $x168 : int, $x169 : int, $x170 : int, $x171 : int, $x172 : int, $x173 : int, $x174 : int, $x175 : int, $x176 : int, $x177 : int, $x178 : int, $x179 : int, $x180 : int, $x181 : int, $x182 : int, $x183 : int, $x184 : int, $x185 : int, $x186 : int, $x187 : int, $x188 : int, $x189 : int, $x190 : int, $x191 : int, $x192 : int, $x193 : int, $x194 : int, $x195 : int, $x196 : int, $x197 : int, $x198 : int, $x199 : int, $x200 : int, $x201 : int, $x202 : int, $x203 : int, $x204 : int, $x205 : int, $x206 : int, $x207 : int, $x208 : int, $x209 : int, $x210 : int, $x211 : int, $x212 : int, $x213 : int, $x214 : int, $x215 : int, $x216 : int, $x217 : int, $x218 : int, $x219 : int, $x220 : int, $x221 : int, $x222 : int, $x223 : int, $x224 : int, $x225 : int, $x226 : int, $x227 : int, $x228 : int, $x229 : int, $x230 : int, $x231 : int, $x232 : int, $x233 : int, $x234 : int, $x235 : int, $x236 : int, $x237 : int, $x238 : int, $x239 : int, $x240 : int, $x241 : int, $x242 : int, $x243 : int, $x244 : int, $x245 : int, $x246 : int, $x247 : int, $x248 : int, $x249 : int, $x250 : int, $x251 : int, $x252 : int, $x253 : int, $x254 : int, $x255 : int) {
    
    return $x255;
  }

  static method args_max_count_mulnum : Complex_2d ($x1 : int, $x2 : int, $x3 : int, $x4 : int, $x5 : int, $x6 : int, $x7 : int, $x8 : int, $x9 : int, $x10 : int, $x11 : int, $x12 : int, $x13 : int, $x14 : int, $x15 : int, $x16 : int, $x17 : int, $x18 : int, $x19 : int, $x20 : int, $x21 : int, $x22 : int, $x23 : int, $x24 : int, $x25 : int, $x26 : int, $x27 : int, $x28 : int, $x29 : int, $x30 : int, $x31 : int, $x32 : int, $x33 : int, $x34 : int, $x35 : int, $x36 : int, $x37 : int, $x38 : int, $x39 : int, $x40 : int, $x41 : int, $x42 : int, $x43 : int, $x44 : int, $x45 : int, $x46 : int, $x47 : int, $x48 : int, $x49 : int, $x50 : int, $x51 : int, $x52 : int, $x53 : int, $x54 : int, $x55 : int, $x56 : int, $x57 : int, $x58 : int, $x59 : int, $x60 : int, $x61 : int, $x62 : int, $x63 : int, $x64 : int, $x65 : int, $x66 : int, $x67 : int, $x68 : int, $x69 : int, $x70 : int, $x71 : int, $x72 : int, $x73 : int, $x74 : int, $x75 : int, $x76 : int, $x77 : int, $x78 : int, $x79 : int, $x80 : int, $x81 : int, $x82 : int, $x83 : int, $x84 : int, $x85 : int, $x86 : int, $x87 : int, $x88 : int, $x89 : int, $x90 : int, $x91 : int, $x92 : int, $x93 : int, $x94 : int, $x95 : int, $x96 : int, $x97 : int, $x98 : int, $x99 : int, $x100 : int, $x101 : int, $x102 : int, $x103 : int, $x104 : int, $x105 : int, $x106 : int, $x107 : int, $x108 : int, $x109 : int, $x110 : int, $x111 : int, $x112 : int, $x113 : int, $x114 : int, $x115 : int, $x116 : int, $x117 : int, $x118 : int, $x119 : int, $x120 : int, $x121 : int, $x122 : int, $x123 : int, $x124 : int, $x125 : int, $x126 : int, $x127 : int, $x128 : int, $x129 : int, $x130 : int, $x131 : int, $x132 : int, $x133 : int, $x134 : int, $x135 : int, $x136 : int, $x137 : int, $x138 : int, $x139 : int, $x140 : int, $x141 : int, $x142 : int, $x143 : int, $x144 : int, $x145 : int, $x146 : int, $x147 : int, $x148 : int, $x149 : int, $x150 : int, $x151 : int, $x152 : int, $x153 : int, $x154 : int, $x155 : int, $x156 : int, $x157 : int, $x158 : int, $x159 : int, $x160 : int, $x161 : int, $x162 : int, $x163 : int, $x164 : int, $x165 : int, $x166 : int, $x167 : int, $x168 : int, $x169 : int, $x170 : int, $x171 : int, $x172 : int, $x173 : int, $x174 : int, $x175 : int, $x176 : int, $x177 : int, $x178 : int, $x179 : int, $x180 : int, $x181 : int, $x182 : int, $x183 : int, $x184 : int, $x185 : int, $x186 : int, $x187 : int, $x188 : int, $x189 : int, $x190 : int, $x191 : int, $x192 : int, $x193 : int, $x194 : int, $x195 : int, $x196 : int, $x197 : int, $x198 : int, $x199 : int, $x200 : int, $x201 : int, $x202 : int, $x203 : int, $x204 : int, $x205 : int, $x206 : int, $x207 : int, $x208 : int, $x209 : int, $x210 : int, $x211 : int, $x212 : int, $x213 : int, $x214 : int, $x215 : int, $x216 : int, $x217 : int, $x218 : int, $x219 : int, $x220 : int, $x221 : int, $x222 : int, $x223 : int, $x224 : int, $x225 : int, $x226 : int, $x227 : int, $x228 : int, $x229 : int, $x230 : int, $x231 : int, $x232 : int, $x233 : int, $x234 : int, $x235 : int, $x236 : int, $x237 : int, $x238 : int, $x239 : int, $x240 : int, $x241 : int, $x242 : int, $x243 : int, $x244 : int, $x245 : int, $x246 : int, $x247 : int, $x248 : int, $x249 : int, $x250 : int, $x251 : int, $x252 : int, $x253 : int, $x254 : Complex_2d) {
    
    return $x254;
  }
  
  precompile static method precompile_sum : int ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }
  
  static method optional_args : int () {
    
    # byte
    {
      {
        my $value = &optional_args_byte0;
        unless ($value == 0) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_byte0(127);
        unless ($value == 127) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_byte_max;
        unless ($value == 127) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_byte_min;
        unless ($value == -128) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_byte_min_long;
        unless ($value == -128) {
          return 0;
        }
      }
    }
    
    
    # short
    {
      {
        my $value = &optional_args_short0;
        unless ($value == 0) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_short0(32767);
        unless ($value == 32767) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_short_max;
        unless ($value == 32767) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_short_min;
        unless ($value == -32768) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_short_min_long;
        unless ($value == -32768) {
          return 0;
        }
      }
    }

    # int
    {
      {
        my $value = &optional_args_int0;
        unless ($value == 0) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_int0(2147483647);
        unless ($value == 2147483647) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_int_max;
        unless ($value == 2147483647) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_int_min;
        unless ($value == -2147483648) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_int_min_long;
        unless ($value == -2147483648) {
          return 0;
        }
      }
    }
    
    # long
    {
      {
        my $value = &optional_args_long0;
        unless ($value == 0) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_long_int_minus1;
        unless ($value == -1) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_long0(9223372036854775807L);
        unless ($value == 9223372036854775807L) {
          return 0;
        }
      }
      {
        my $value = &optional_args_long_min;
        unless ($value == 9223372036854775807L) {
          return 0;
        }
      }
      {
        my $value = &optional_args_long_min_new_syntax;
        unless ($value == 9223372036854775807L) {
          return 0;
        }
      }
      {
        my $value = &optional_args_long_max;
        unless ($value == -9223372036854775808L) {
          return 0;
        }
      }
    }
    
    # float
    {
      {
        my $value = &optional_args_float0;
        unless ($value == 1.5f) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_float0(2.5f);
        unless ($value == 2.5f) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_float_int_minus1;
        unless ($value == -1) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_float_long_minus1;
        unless ($value == -1) {
          return 0;
        }
      }
    }
    
    # double
    {
      {
        my $value = &optional_args_double0;
        unless ($value == 2147483647.5) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_double0(2147483647.55);
        unless ($value == 2147483647.55) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_double_int_minus1;
        unless ($value == -1) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_double_long_minus1;
        unless ($value == -1) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_double_float_minus1_5;
        unless ($value == -1.5) {
          return 0;
        }
      }
    }
    
    # object
    {
      {
        my $value = &optional_args_object;
        unless ($value == undef) {
          return 0;
        }
      }
      {
        my $value = &optional_args_object_dim1;
        unless ($value == undef) {
          return 0;
        }
      }
      {
        my $value = &optional_args_string_dim2;
        unless ($value == undef) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_string;
        unless ($value == undef) {
          return 0;
        }
      }
      
      {
        my $value = &optional_args_mulnum;
        unless ($value->{re} == 0) {
          return 0;
        }
        unless ($value->{im} == 0) {
          return 0;
        }
      }
    }
    
    # Numeric reference
    {
      {
        my $success = &optional_args_numeric_ref(1);
        unless ($success) {
          return 0;
        }
      }
    }
    
    # Multi-numeric reference
    {
      {
        my $success = &optional_args_multi_numeric_ref(1);
        unless ($success) {
          return 0;
        }
      }
    }
    
    {
      {
        my $values = &optional_args_byte_three_optional;
        unless ($values->[0]->(int) == 1) {
          return 0;
        }
        unless ($values->[1]->(int) == 2) {
          return 0;
        }
        unless ($values->[2]->(int) == 3) {
          return 0;
        }
      }
      {
        my $values = &optional_args_byte_three_optional(5);
        unless ($values->[0]->(int) == 5) {
          return 0;
        }
        unless ($values->[1]->(int) == 2) {
          return 0;
        }
        unless ($values->[2]->(int) == 3) {
          return 0;
        }
      }
      {
        my $values = &optional_args_byte_three_optional(5, 6);
        unless ($values->[0]->(int) == 5) {
          return 0;
        }
        unless ($values->[1]->(int) == 6) {
          return 0;
        }
        unless ($values->[2]->(int) == 3) {
          return 0;
        }
      }
      {
        my $values = &optional_args_byte_three_optional(5, 6, 7);
        unless ($values->[0]->(int) == 5) {
          return 0;
        }
        unless ($values->[1]->(int) == 6) {
          return 0;
        }
        unless ($values->[2]->(int) == 7) {
          return 0;
        }
      }
    }
    
    {
      {
        my $values = &optional_args_byte_one_required_tow_optional(5);
        unless ($values->[0]->(int) == 5) {
          return 0;
        }
        unless ($values->[1]->(int) == 2) {
          return 0;
        }
        unless ($values->[2]->(int) == 3) {
          return 0;
        }
      }
      {
        my $values = &optional_args_byte_one_required_tow_optional(5, 6);
        unless ($values->[0]->(int) == 5) {
          return 0;
        }
        unless ($values->[1]->(int) == 6) {
          return 0;
        }
        unless ($values->[2]->(int) == 3) {
          return 0;
        }
      }
      {
        my $values = &optional_args_byte_one_required_tow_optional(5, 6, 7);
        unless ($values->[0]->(int) == 5) {
          return 0;
        }
        unless ($values->[1]->(int) == 6) {
          return 0;
        }
        unless ($values->[2]->(int) == 7) {
          return 0;
        }
      }
      
    }
    
    # Interface optional argument
    {
      my $anon = (TestCase::Interface::OptionalArgument)method : int ($value : int = 2) {
        return $value;
      };
      
      {
        my $ret = $anon->();
        
        unless ($ret == 2) {
          warn $ret;
          return 0;
        }
      }
      
      {
        my $ret = $anon->(3);
        
        unless ($ret == 3) {
          warn $ret;
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method optional_args_byte_three_optional : Int[]  ($args0 : int = 1, $args1 : int = 2, $args2 : int = 3) {
    return [(Int)$args0, $args1, $args2];
  }
  
  static method optional_args_byte_one_required_tow_optional : Int[]  ($args0 : int, $args1 : int = 2, $args2 : int = 3) {
    return [(Int)$args0, $args1, $args2];
  }
  
  static method optional_args_byte0 : byte ($arg : byte = 0) {
    return $arg;
  }
  static method optional_args_byte_max : byte ($arg : byte = 127) {
    return $arg;
  }
  static method optional_args_byte_min : byte ($arg : byte = -128) {
    return $arg;
  }
  
  static method optional_args_byte_min_long : byte ($arg : byte = -128L) {
    return $arg;
  }
  
  static method optional_args_short0 : short ($arg : short = 0) {
    return $arg;
  }
  static method optional_args_short_max : short ($arg : short = 32767) {
    return $arg;
  }
  static method optional_args_short_min : short ($arg : short = -32768) {
    return $arg;
  }
  
  static method optional_args_short_min_long : short ($arg : short = -32768L) {
    return $arg;
  }

  static method optional_args_int0 : int ($arg : int = 0) {
    return $arg;
  }
  static method optional_args_int_max : int ($arg : int = 2147483647) {
    return $arg;
  }
  static method optional_args_int_min : int ($arg : int = -2147483648) {
    return $arg;
  }
  
  static method optional_args_int_min_long : int ($arg : int = -2147483648L) {
    return $arg;
  }
  
  static method optional_args_long0 : long ($arg : long = 0) {
    return $arg;
  }
  static method optional_args_long_int_minus1 : long ($arg : long = -1) {
    return $arg;
  }
  static method optional_args_long_min : long ($arg : long = 9223372036854775807L) {
    return $arg;
  }
  static method optional_args_long_min_new_syntax : long ($arg : long = 9223372036854775807L) {
    return $arg;
  }
  static method optional_args_long_max : long ($arg : long = -9223372036854775808L) {
    return $arg;
  }
  
  static method optional_args_float0 : float ($arg : float = 1.5f) {
    return $arg;
  }
  
  static method optional_args_float_int_minus1 : float ($arg : float = -1) {
    return $arg;
  }
  
  static method optional_args_float_long_minus1 : float ($arg : float = -1L) {
    return $arg;
  }
  
  static method optional_args_double0 : double ($arg : double = 2147483647.5) {
    return $arg;
  }
  
  static method optional_args_double_int_minus1 : double ($arg : double = -1) {
    return $arg;
  }
  
  static method optional_args_double_long_minus1 : double ($arg : double = -1L) {
    return $arg;
  }
  
  static method optional_args_double_float_minus1_5 : double ($arg : double = -1.5f) {
    return $arg;
  }
  
  static method optional_args_object : object ($arg : object = undef) {
    return $arg;
  }
  static method optional_args_object_dim1 : object ($arg : object[] = undef) {
    return $arg;
  }
  static method optional_args_string_dim2 : object ($arg : string[][] = undef) {
    return $arg;
  }
  static method optional_args_string : string ($arg : string = undef) {
    return $arg;
  }
  
  static method optional_args_mulnum : Complex_2d ($arg : Complex_2d = undef) {
    return $arg;
  }
  
  static method optional_args_numeric_ref : int ($arg : int, $arg_byte_ref : byte* = undef, $arg_short_ref : short* = undef,$arg_int_ref : int* = undef, $arg_long_ref : long* = undef, $arg_float_ref : float* = undef, $arg_double_ref : double* = undef,) {
    
    if ($arg_byte_ref) {
      return 0;
    }
    
    if ($arg_byte_ref) {
      return 0;
    }
    
    if ($arg_short_ref) {
      return 0;
    }
    
    if ($arg_int_ref) {
      return 0;
    }
    
    if ($arg_long_ref) {
      return 0;
    }
    
    if ($arg_float_ref) {
      return 0;
    }
    
    if ($arg_double_ref) {
      return 0;
    }
    
    # Exceptions
    {
      {
        eval { $$arg_byte_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_short_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_int_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_long_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_float_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_double_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_byte_ref = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_short_ref = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_int_ref = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_long_ref = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_float_ref = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_double_ref = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method optional_args_multi_numeric_ref : int ($arg : int, $arg_byte_ref : TestCase::Point_3b* = undef, $arg_short_ref : TestCase::Point_3s* = undef, $arg_int_ref : TestCase::Point_3i* = undef, $arg_long_ref : TestCase::Point_3l* = undef, $arg_float_ref : TestCase::Point_3f* = undef, $arg_double_ref : TestCase::Point_3d* = undef) {
    
    if ($arg_byte_ref) {
      return 0;
    }
    
    if ($arg_short_ref) {
      return 0;
    }
    
    if ($arg_int_ref) {
      return 0;
    }
    
    if ($arg_long_ref) {
      return 0;
    }
    
    if ($arg_float_ref) {
      return 0;
    }
    
    if ($arg_double_ref) {
      return 0;
    }
    
    # Exceptions
    {
      {
        eval { $$arg_byte_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_short_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_int_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_long_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_float_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $$arg_double_ref; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_byte_ref->{x}; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_short_ref->{x}; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_int_ref->{x}; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_long_ref->{x}; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_float_ref->{x}; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_double_ref->{x}; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_byte_ref->{x} = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_short_ref->{x} = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_int_ref->{x} = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_long_ref->{x} = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_float_ref->{x} = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
      {
        eval { $arg_double_ref->{x} = 1; }
        
        unless (Fn->contains($@, "An reference access failed. The reference must be defined.")) {
          return 0;
        }
      }
      
    }
    return 1;
  }
  
  static method deep_recursion : int () {
    eval { &recursion; };
    unless (Fn->contains($@, "Deep recursion occurs. \$depth of a method call must be less than 10000")) {
      return 0;
    }
    
    return 1;
  }
  
  static method recursion : void () {
    &recursion;
  }

  static method test_arg_byte : int () {
    
    my $value = Fn->BYTE_MIN;
    
    my $result = &arg_byte($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_short : int () {
    
    my $value = Fn->SHORT_MIN;
    
    my $result = &arg_short($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_int : int () {
    
    my $value = Fn->INT_MIN;
    
    my $result = &arg_int($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_long : int () {
    
    my $value = Fn->LONG_MIN;
    
    my $result = &arg_long($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_float : int () {
    
    my $value = Fn->FLOAT_MIN;
    
    my $result = &arg_float($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_double : int () {
    
    my $value = Fn->DOUBLE_MIN;
    
    my $result = &arg_double($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }

  static method test_arg_object : int () {
    
    my $value = Point->new;
    
    my $result = &arg_object($value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }

  static method arg_byte : byte ($value : byte) {
    return $value;
  }
  static method arg_short : short ($value : short) {
    return $value;
  }
  static method arg_int : int ($value : int) {
    return $value;
  }
  static method arg_long : long ($value : long) {
    return $value;
  }
  static method arg_float : float ($value : float) {
    return $value;
  }
  static method arg_double : double ($value : double) {
    return $value;
  }
  static method arg_object : object ($value : object) {
    return $value;
  }
  
  static method arg_ref : byte ($value : byte*) {
    return $$value;
  }
  
  static method test_arg_ref : int () {
    
    my $value = Fn->BYTE_MIN;
    
    my $result = &arg_ref(\$value);
    
    unless ($result == $value) {
      return 0;
    }
    
    return 1;
  }

  static method test_arg_mulnum_byte : int () {
    
    my $value : TestCase::Point_3b;
    $value->{x} = Fn->BYTE_MIN;
    $value->{y} = 2;
    
    my $result = &arg_mulnum_byte($value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_mulnum_short : int () {
    
    my $value : TestCase::Point_3s;
    $value->{x} = Fn->SHORT_MIN;
    $value->{y} = 2;
    
    my $result = &arg_mulnum_short($value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_mulnum_int : int () {
    
    my $value : TestCase::Point_3i;
    $value->{x} = Fn->INT_MIN;
    $value->{y} = 2;
    
    my $result = &arg_mulnum_int($value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_mulnum_long : int () {
    
    my $value : TestCase::Point_3l;
    $value->{x} = Fn->LONG_MIN;
    $value->{y} = 2;
    
    my $result = &arg_mulnum_long($value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_mulnum_float : int () {
    
    my $value : TestCase::Point_3f;
    $value->{x} = Fn->FLOAT_MIN;
    $value->{y} = 2f;
    
    my $result = &arg_mulnum_float($value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }
  static method test_arg_mulnum_double : int () {
    
    my $value : TestCase::Point_3d;
    $value->{x} = Fn->DOUBLE_MIN;
    $value->{y} = 2;
    
    my $result = &arg_mulnum_double($value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }

  static method arg_mulnum_byte : TestCase::Point_3b ($value : TestCase::Point_3b) {
    return $value;
  }
  static method arg_mulnum_short : TestCase::Point_3s ($value : TestCase::Point_3s) {
    return $value;
  }
  static method arg_mulnum_int : TestCase::Point_3i ($value : TestCase::Point_3i) {
    return $value;
  }
  static method arg_mulnum_long : TestCase::Point_3l ($value : TestCase::Point_3l) {
    return $value;
  }
  static method arg_mulnum_float : TestCase::Point_3f ($value : TestCase::Point_3f) {
    return $value;
  }
  static method arg_mulnum_double : TestCase::Point_3d ($value : TestCase::Point_3d) {
    return $value;
  }

  static method test_arg_mulnum_ref : int () {
    
    my $value : TestCase::Point_3b;
    $value->{x} = Fn->BYTE_MIN;
    $value->{y} = 2;
    
    my $result = &arg_mulnum_ref(\$value);
    
    unless ($result->{x} == $value->{x}) {
      return 0;
    }
    
    unless ($result->{y} == $value->{y}) {
      return 0;
    }
    
    return 1;
  }
  static method arg_mulnum_ref : TestCase::Point_3b ($value : TestCase::Point_3b*) {
    return $$value;
  }

  static method args_width_0 : int () {
    my $args_width = args_width;
    
    return $args_width;
  }
  
  static method args_width_1 : int ($args0 : int) {
    my $args_width = args_width;
    
    return $args_width;
  }
  
  static method args_width_2 : int ($args0 : int, $args1 : int = 0) {
    my $args_width = args_width;
    
    return $args_width;
  }
  
  static method args_width_4 : int ($args_2d : Complex_2d, $args0 : int = 0, $args1 : int = 0) {
    my $args_width = args_width;
    
    return $args_width;
  }

  method instance_method_args_width_2 : int ($args0 : int, $args1 : int = 0) {
    my $args_width = args_width;
    
    return $args_width;
  }

  static method args_width : int () {
    {
      my $args_length = &args_width_0;
      unless ($args_length == 0) {
        return 0;
      }
    }
    
    {
      my $args_length = &args_width_1(0);
      unless ($args_length == 1) {
        return 0;
      }
    }
    
    {
      my $args_length = &args_width_2(0);
      unless ($args_length == 1) {
        return 0;
      }
    }
    
    {
      my $args_length = &args_width_2(0, 0);
      unless ($args_length == 2) {
        return 0;
      }
    }
    
    {
      my $object = new TestCase::Operator::MethodCall;
      my $args_length = $object->instance_method_args_width_2(0);
      unless ($args_length == 2) {
        return 0;
      }
    }
    
    {
      my $object = new TestCase::Operator::MethodCall;
      my $args_length = $object->instance_method_args_width_2(0, 0);
      unless ($args_length == 3) {
        return 0;
      }
    }
    
    {
      my $z : Complex_2d;
      my $args_length = &args_width_4($z, 0, 0);
      unless ($args_length == 4) {
        return 0;
      }
    }
    
    {
      my $z : Complex_2d;
      my $args_length = &args_width_4($z);
      unless ($args_length == 2) {
        return 0;
      }
    }
    
    return 1;
  }
  
  method interface_shared1 : string ($num : int) {
    return undef;
  }
  
  static method call_interface_method_exception : int () {
    {
      my $self = new TestCase::Operator::MethodCall;
      my $interface = (TestCase::Interface::Type)$self;
      
      eval { $interface->to_string; }
      
      unless (Fn->contains($@, "An instance method call failed. TestCase::Operator::MethodCall#to_string method is not found.")) {
        return 0;
      }
    }
    
    {
      my $interface = (TestCase::Interface::Type)undef;
      
      eval { $interface->to_string; }
      
      unless (Fn->contains($@, "Can't call to_string method on undefined value.")) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method call_recursive : int () {
    
    eval { TestCase::Simple->call_recursive; }
    
    unless (Fn->contains($@, "Deep recursion occurs.")) {
      return 0;
    }
    
    return 1;
  }
  
  static method inheritance : int () {
    
    # Type checking of object argument 
    {
      {
        {
          my $simple = TestCase::Simple->new;
          
          my $input = "aaa";
          
          my $result = $simple->arg_object($input);
          
          unless ($result is_compile_type object) {
            return 0;
          }
          
          unless ($result is_type string) {
            return 0;
          }
          
          unless ($result == $input) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChild->new;
          
          my $input = "aaa";
          
          my $result = $simple->arg_object($input);
          
          unless ($result is_compile_type string) {
            return 0;
          }
          
          unless ($result is_type string) {
            return 0;
          }
          
          unless ($result == $input) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChild->new;
          
          my $input = "aaa";
          
          my $result = $simple->(TestCase::Simple)->arg_object($input);
          
          unless ($result is_compile_type object) {
            return 0;
          }
          
          unless ($result is_type string) {
            return 0;
          }
          
          unless ($result == $input) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChild->new;
          
          my $input = Int->new(1);
          
          eval { $simple->(TestCase::Simple)->arg_object($input); }
          
          unless (Fn->contains($@, q'1th argument must be assigned to the type of 1th argument of TestCase::SimpleChild#arg_object method.')) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChildOfChild->new;
          
          my $input = new string[0];
          
          my $ret = $simple->(TestCase::Simple)->arg_any_object_array($input);
          
          unless ($ret == $input) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChildOfChild->new;
          
          my $input = new Int[0];
          
          eval { $simple->(TestCase::Simple)->arg_any_object_array($input); }
          
          unless (Fn->contains($@, q'he 1th argument must be assigned to the type of 1th argument of TestCase::SimpleChildOfChild#arg_any_object_array method.')) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChildOfChild->new;
          
          my $input = new Point3D[0];
          
          my $ret = $simple->(TestCase::Simple)->arg_inheritance($input);
          
          unless ($ret == $input) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChildOfChild->new;
          
          my $input = new Point[0];
          
          eval { $simple->(TestCase::Simple)->arg_inheritance($input); }
          
          unless (Fn->contains($@, q'he 1th argument must be assigned to the type of 1th argument of TestCase::SimpleChildOfChild#arg_inheritance method.')) {
            return 0;
          }
        }
      }
      
      {
        {
          my $simple = TestCase::Simple->new;
          
          my $result = $simple->arg_object_option;
          
          unless ($result is_compile_type object) {
            return 0;
          }
          
          unless ($result == undef) {
            return 0;
          }
        }
        
        {
          my $simple = TestCase::SimpleChild->new;
          
          my $input = "aaa";
          
          my $result = $simple->arg_object_option($input);
          
          unless ($result is_compile_type string) {
            return 0;
          }
          
          unless ($result is_type string) {
            return 0;
          }
          
          unless ($result == $input) {
            return 0;
          }
        }
        
        {
          my $minimal = TestCase::Minimal->new;
          
          # Call anon method
          my $ret = $minimal->TestCase::Minimal::();
          
          unless ($ret == 3) {
            return 0;
          }
        }
      }
    }
    
    return 1;
  }
  
  static method varargs : int () {
    
    {
      my $ret = &varargs_method(1, "abc", 2);
      
      unless ($ret eq "abc2") {
        return 0;
      }
    }
    
    {
      my $ret = &varargs_method(1, (object...)[(object)"abc", 2]);
      
      unless ($ret eq "abc2") {
        return 0;
      }
    }
    
    {
      my $success = &varargs_method_zero();
      
      unless ($success) {
        return 0;
      }
    }
    
    {
      my $success = &varargs_method_no_type_cast([(object)"abc", 2]);
      
      unless ($success) {
        return 0;
      }
    }
    
    {
      my $success = &varargs_method_no_type_cast((object[])[(object)"abc", 2]);
      
      unless ($success) {
        return 0;
      }
    }
    
    {
      {
        my $args = &varargs_options({foo => 1, bar => 2});
        
        unless ($args->[0]->(object[])->[0]->(string) eq "foo") {
          return 0;
        }
        
        unless ($args->[0]->(object[])->[1]->(int) == 1) {
          return 0;
        }
        
        unless ($args->[0]->(object[])->[2]->(string) eq "bar") {
          return 0;
        }
        
        unless ($args->[0]->(object[])->[3]->(int) == 2) {
          return 0;
        }
        
      }
      
      {
        my $args = &varargs_options("a", {foo => 1, bar => 2}, "b");
        
        unless ($args->[0]->(string) eq "a") {
          return 0;
        }
        
        unless ($args->[1]->(object[])->[0]->(string) eq "foo") {
          return 0;
        }
        
        unless ($args->[1]->(object[])->[1]->(int) == 1) {
          return 0;
        }
        
        unless ($args->[1]->(object[])->[2]->(string) eq "bar") {
          return 0;
        }
        
        unless ($args->[1]->(object[])->[3]->(int) == 2) {
          return 0;
        }
        
        unless ($args->[2]->(string) eq "b") {
          return 0;
        }
        
      }
    }
    
    return 1;
  }
  
  static method varargs_method : string ($var1 : int, $args : object...) {
    
    my $ret = $args->[0]->(string) . $args->[1]->(int);
    
    return $ret;
  }
  
  static method varargs_method_zero : string ($args : object...) {
    
    unless ($args isa object[]) {
      return 0;
    }
    
    unless (@$args == 0) {
      return 0;
    }
    
    return 1;
  }
  
  static method varargs_method_no_type_cast : string ($args : object...) {
    
    unless ($args isa object[]) {
      return 0;
    }
    
    unless (@$args == 1) {
      return 0;
    }
    
    unless ($args->[0] isa object[]) {
      return 0;
    }
    
    return 1;
  }
  
  static method varargs_options : object[] ($args : object...) {
    
    return $args;
  }
  
  static method args_scope : int ($var : int = 1) {
    
    my $var = 2;
    
    unless ($var == 2) {
      return 0;
    }
    
    my $self = Int->new(3);
    
    my $cb = [$self : Int] method : int () {
      return $self->value;
    };
    
    unless ($cb->() == 3) {
      return 0;
    }
    
    return 1;
  }
  
  static method union_mapping : int () {
    
    # Test mapping: Int[] -> int[]
    {
      my $int_object_array = [Int->new(1), Int->new(2)];
      
      # Return type should be auto-cast to int[] at compile time
      my $ret = &union_mapping_method($int_object_array);
      
      # Verify the static type is int[]
      unless ($ret is_compile_type int[]) {
        return 0;
      }
      
      unless ($ret->[0] == 1 && $ret->[1] == 2) {
        return 0;
      }
    }
    
    # Test mapping: Long[] -> long[]
    {
      my $long_object_array = [Long->new(4L), Long->new(5L)];
      
      # Return type should be auto-cast to long[] at compile time
      my $ret = &union_mapping_method($long_object_array);
      
      # Verify the static type is long[]
      unless ($ret is_compile_type long[]) {
        return 0;
      }
      
      unless ($ret->[0] == 4L && $ret->[1] == 5L) {
        return 0;
      }
    }

    # Test fallback: No match
    {
      {
        # No match found, so return type should remain as the union type
        my $ret = &union_mapping_method([Float->new(4f), Float->new(5f)]);
        
        # Verify the static type is still the original union type
        unless ($ret is_compile_type object) {
          return 0;
        }
        
        unless ($ret->(Float[])->[0]->value == 4f && $ret->(Float[])->[1]->value == 5f) {
          return 0;
        }
      }
      
      {
        # No match found, so return type should remain as the union type
        my $ret = &union_mapping_method(["1", "2"]);
        
        # Verify the static type is still the original union type
        unless ($ret is_compile_type object) {
          return 0;
        }
        
        unless ($ret->(string[])->[0] eq "1" && $ret->(string[])->[1] eq "2") {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  # Mapping definition:
  # arg index 0 (Int[])  -> return index 0 (int[])
  # arg index 1 (Long[]) -> return index 1 (long[])
  static method union_mapping_method : int[]|long[]|object ($arg : Int[]|Long[]|Float[]|object) {
    if ($arg isa Int[]) {
      my $int_object_array = (Int[])$arg;
      my $int_array = new int[@$int_object_array];
      for (my $i = 0; $i < @$int_object_array; $i++) {
        $int_array->[$i] = $int_object_array->[$i]->value;
      }
      return $int_array;
    }
    elsif ($arg isa Long[]) {
      my $long_object_array = (Long[])$arg;
      my $long_array = new long[@$long_object_array];
      for (my $i = 0; $i < @$long_object_array; $i++) {
        $long_array->[$i] = $long_object_array->[$i]->value;
      }
      return $long_array;
    }
    
    return $arg;
  }
  
}
