class TestCase::Module::Native::BasicType {
  use Native;
  use Fn;
  use Array;
  use Point;
  use Native::Constant;
  use Point3D;
  use TestCase::Interface::Args1;

  static method get_methods : int () {
    
    {
      my $current_rntime = Native->get_current_runtime;
      
      my $basic_type = $current_rntime->get_basic_type_by_name("Int");
      
      my $methods = $basic_type->get_methods;
      
      {
        my $callback = method : int ($element : object) {
          if ($element->(Native::Method)->get_name eq "value") { return 1; }
        };
        
        unless (@{Fn->grep($callback, $methods)}) {
          return 0;
        }
      }
    }
    
    # Extra
    {
      # get_basic_type_in_version_from
      {
        my $current_rntime = Native->get_current_runtime;
        
        my $basic_type = $current_rntime->get_basic_type_by_name("Int");
        
        my $basic_type_in_version_from = $basic_type->get_basic_type_in_version_from;
        
        unless ($basic_type_in_version_from->get_name eq "SPVM") {
          return 0;
        }
      }
      
      # get_parent
      {
        my $current_rntime = Native->get_current_runtime;
        
        my $basic_type = $current_rntime->get_basic_type_by_name("Point3D");
        
        my $parent_basic_type = $basic_type->get_parent;
        
        unless ($parent_basic_type->get_name eq "Point") {
          return 0;
        }
      }
      
      # get_method_by_name
      {
        my $current_rntime = Native->get_current_runtime;
        
        my $basic_type = $current_rntime->get_basic_type_by_name("Int");
        
        my $method = $basic_type->get_method_by_name("value");
        
        my $args_length = $method->get_args_length;
        
        unless ($args_length == 1) {
          return 0;
        }
      }
      
      # Anon method
      {
        my $ref = [(string)undef];
        my $cb1 = (object) [$ref : string[]] method : void ($arg : string) {
          $ref->[0] = $arg;
        };
        
        my $ref2 = [(string)undef, undef];
        my $cb2 = (object) [$ref2 : string[]] method : void ($arg1 : string, $arg2 : string) {
          $ref2->[0] = $arg1;
          $ref2->[1] = $arg2;
        };
        
        my $type_name = type_name $cb1;
        
        my $current_rntime = Native->get_current_runtime;
        
        my $basic_type = $current_rntime->get_basic_type_by_name($type_name);
        
        my $method = $basic_type->get_method_by_name("");
        
        my $args_length = $method->get_args_length;
        
        unless ($args_length == 2) {
          return 0;
        }
        
        my $cb_args1 = (TestCase::Interface::Args1)$cb1;
        
        $cb_args1->("abc");
        
        unless ($ref->[0] eq "abc") {
          return 0;
        }
        
        $cb_args1->("D", "E");
        
        unless ($ref->[0] eq "D") {
          return 0;
        }
        
        my $cb_args2 = (TestCase::Interface::Args1)$cb2;
        
        $cb_args2->("A", "B");
        
        unless ($ref2->[0] eq "A") {
          return 0;
        }
        
        unless ($ref2->[1] eq "B") {
          return 0;
        }
        
        
      }
    }
    
    return 1;
  }
  
  static method get_fields : int () {
    
    {
      my $current_rntime = Native->get_current_runtime;
      
      my $basic_type = $current_rntime->get_basic_type_by_name("Int");
      
      my $fields = $basic_type->get_fields;
      
      {
        my $callback = method : int ($element : object) {
          if ($element->(Native::Field)->get_name eq "value") { return 1; }
        };
        
        unless (@{Fn->grep($callback, $fields)}) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method get_class_vars : int () {
    
    {
      my $current_rntime = Native->get_current_runtime;
      
      my $basic_type = $current_rntime->get_basic_type_by_name("Bool");
      
      my $class_vars = $basic_type->get_class_vars;
      
      {
        my $callback = method : int ($element : object) {
          if ($element->(Native::ClassVar)->get_name eq "\$TRUE") { return 1; }
        };
        
        unless (@{Fn->grep($callback, $class_vars)}) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
}
