class TestCase::Lib::Fn2 {
  use EqualityChecker::SameObject;
  
  static method copy_array_byte : int () {
    # Copy array
    {
      my $nums = [(byte)1, 2, Fn->INT8_MIN()];
      my $nums_out = Fn->copy_array_byte($nums);

      unless ($nums->[0] == 1) {
        return 0;
      }

      unless ($nums->[1] == 2) {
        return 0;
      }

      unless ($nums->[2] == Fn->INT8_MIN()) {
        return 0;
      }

      unless (@$nums_out == 3) {
        return 0;
      }
    }
    
    # Array is undef
    {
      my $output = Fn->copy_array_byte(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_short : int () {
    # Copy array
    {
      my $nums = [(short)1, 2, Fn->INT16_MIN()];
      my $nums_out = Fn->copy_array_short($nums);

      unless ($nums->[0] == 1) {
        return 0;
      }

      unless ($nums->[1] == 2) {
        return 0;
      }

      unless ($nums->[2] == Fn->INT16_MIN()) {
        return 0;
      }

      unless (@$nums_out == 3) {
        return 0;
      }
    }
    
    # Array is undef
    {
      my $output = Fn->copy_array_short(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_int : int () {
    # Copy array
    {
      my $nums = [(int)1, 2, Fn->INT32_MIN()];
      my $nums_out = Fn->copy_array_int($nums);

      unless ($nums->[0] == 1) {
        return 0;
      }

      unless ($nums->[1] == 2) {
        return 0;
      }

      unless ($nums->[2] == Fn->INT32_MIN()) {
        return 0;
      }

      unless (@$nums_out == 3) {
        return 0;
      }
    }

    # Array is undef
    {
      my $output = Fn->copy_array_int(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_long : int () {
    # Copy array
    {
      my $nums = [(long)1, 2, Fn->INT64_MIN()];
      my $nums_out = Fn->copy_array_long($nums);

      unless ($nums->[0] == 1) {
        return 0;
      }

      unless ($nums->[1] == 2) {
        return 0;
      }

      unless ($nums->[2] == Fn->INT64_MIN()) {
        return 0;
      }

      unless (@$nums_out == 3) {
        return 0;
      }
    }

    # Array is undef
    {
      my $output = Fn->copy_array_long(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_float : int () {
    # Copy array
    {
      my $nums = [(float)0.5f, 0.25f, Fn->FLT_MIN()];
      my $nums_out = Fn->copy_array_float($nums);

      unless ($nums->[0] == 0.5) {
        return 0;
      }

      unless ($nums->[1] == 0.25) {
        return 0;
      }

      unless ($nums->[2] == Fn->FLT_MIN()) {
        return 0;
      }

      unless (@$nums_out == 3) {
        return 0;
      }
    }

    # Array is undef
    {
      my $output = Fn->copy_array_float(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_double : int () {
    # Copy array
    {
      my $nums = [(double)0.5, 0.25, Fn->DBL_MIN()];
      my $nums_out = Fn->copy_array_double($nums);

      unless ($nums->[0] == 0.5) {
        return 0;
      }

      unless ($nums->[1] == 0.25) {
        return 0;
      }

      unless ($nums->[2] == Fn->DBL_MIN()) {
        return 0;
      }

      unless (@$nums_out == 3) {
        return 0;
      }
    }

    # Array is undef
    {
      my $output = Fn->copy_array_double(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_string : int () {
    # Copy array
    {
      my $strings = ["abc", "def", "hij"];
      my $strings_out = Fn->copy_array_string($strings);

      unless ($strings->[0] eq $strings_out->[0]) {
        return 0;
      }
      unless ($strings->[1] eq $strings_out->[1]) {
        return 0;
      }
      unless ($strings->[2] eq $strings_out->[2]) {
        return 0;
      }

      unless ($strings->[0] != $strings_out->[0]) {
        return 0;
      }

      unless ($strings->[1] != $strings_out->[1]) {
        return 0;
      }

      unless ($strings->[2] != $strings_out->[2]) {
        return 0;
      }

      unless (@$strings_out == 3) {
        return 0;
      }
    }

    # Array is undef
    {
      my $output = Fn->copy_array_string(undef);
      unless ($output == undef) {
        return 0;
      }
    }

    return 1;
  }

  static method copy_array_object : int () {
    # Copy array
    {
      my $objects = [(object)Int->new(1), Int->new(2), Int->new(Fn->INT32_MIN())];
      my $objects_out = Fn->copy_array_object($objects, method : object ($obj : object) {
        my $int_obj = (Int)$obj;
        my $new_int_obj = Int->new($int_obj->value);
        return $new_int_obj;
      });

      if ($objects->[0] == $objects_out->[0]) {
        return 0;
      }

      if ($objects->[1] == $objects_out->[1]) {
        return 0;
      }

      if ($objects->[2] == $objects_out->[2]) {
        return 0;
      }

      unless ((int)$objects_out->[0] == 1) {
        return 0;
      }

      unless ((int)$objects_out->[1] == 2) {
        return 0;
      }

      unless ((int)$objects_out->[2] == Fn->INT32_MIN()) {
        return 0;
      }

      unless (@$objects_out == 3) {
        return 0;
      }

      unless ($objects != $objects_out) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_byte : int () {
    my $nums1 = [(byte)0, 1, Fn->INT8_MIN()];
    my $nums2 = [(byte)0, 1, Fn->INT8_MIN()];
    my $nums3 = [(byte)0, 1];
    my $nums4 = [(byte)0, 1, 2];
    {
      my $is_equals = Fn->equals_array_byte($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_byte($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_byte($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_byte(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_byte($nums1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_byte(undef, $nums1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_short : int () {
    my $nums1 = [(short)0, 1, Fn->INT16_MIN()];
    my $nums2 = [(short)0, 1, Fn->INT16_MIN()];
    my $nums3 = [(short)0, 1];
    my $nums4 = [(short)0, 1, 2];

    {
      my $is_equals = Fn->equals_array_short($nums1, $nums2);

      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_short($nums1, $nums3);

      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_short($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }

    {
      my $is_equals = Fn->equals_array_short(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_short($nums1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_short(undef, $nums1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_int : int () {
    my $nums1 = [(int)0, 1, Fn->INT32_MIN()];
    my $nums2 = [(int)0, 1, Fn->INT32_MIN()];
    my $nums3 = [(int)0, 1];
    my $nums4 = [(int)0, 1, 2];

    {
      my $is_equals = Fn->equals_array_int($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_int($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_int($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }

    {
      my $is_equals = Fn->equals_array_int(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_int($nums1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_int(undef, $nums1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_long : int () {
    my $nums1 = [(long)0, 1, Fn->INT64_MIN()];
    my $nums2 = [(long)0, 1, Fn->INT64_MIN()];
    my $nums3 = [(long)0, 1];
    my $nums4 = [(long)0, 1, 2];

    {
      my $is_equals = Fn->equals_array_long($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_long($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_long($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }

    {
      my $is_equals = Fn->equals_array_long(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_long($nums1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_long(undef, $nums1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_float : int () {
    my $nums1 = [0.0f, 1.5f, Fn->FLT_MIN()];
    my $nums2 = [0.0f, 1.5f, Fn->FLT_MIN()];
    my $nums3 = [0.0f, 1.5f];
    my $nums4 = [(float)0.0f, 1.5f, 0.5f];

    {
      my $is_equals = Fn->equals_array_float($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_float($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_float($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }

    {
      my $is_equals = Fn->equals_array_float(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_float($nums1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_float(undef, $nums1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_double : int () {
    my $nums1 = [0.0, 1.5, Fn->DBL_MIN()];
    my $nums2 = [0.0, 1.5, Fn->DBL_MIN()];
    my $nums3 = [0.0, 1.5];
    my $nums4 = [(double)0.0, 1.5, 0.5];

    {
      my $is_equals = Fn->equals_array_double($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_double($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_double($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }

    {
      my $is_equals = Fn->equals_array_double(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_double($nums1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_double(undef, $nums1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method equals_array_string : int () {
    my $strings1 = ["abc", "def", "ghi"];
    my $strings2 = ["abc", "def", "ghi"];
    my $strings3 = ["abc", "def"];
    my $strings4 = ["abc", "def", "xxx"];

    {
      my $is_equals = Fn->equals_array_string($strings1, $strings2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_string($strings1, $strings3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_string($strings1, $strings4);
      if ($is_equals) {
        return 0;
      }
    }

    {
      my $is_equals = Fn->equals_array_string(undef, undef);
      if ($is_equals) {
        return 1;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_string($strings1, undef);
      if ($is_equals) {
        return 0;
      }
    }
    
    {
      my $is_equals = Fn->equals_array_string(undef, $strings1);
      if ($is_equals) {
        return 0;
      }
    }

    return 1;
  }
  static method equals_array_object : int () {
    my $minimal1 = TestCase::Minimal->new;
    my $minimal2 = TestCase::Minimal->new;
    my $minimal3 = TestCase::Minimal->new;
    my $minimal4 = TestCase::Minimal->new;
    my $nums1 = [$minimal1, $minimal2, $minimal3];
    my $nums2 = [$minimal1, $minimal2, $minimal3];
    my $nums3 = [$minimal1, $minimal2];
    my $nums4 = [$minimal1, $minimal2, $minimal4];
    my $nums5 = [(object)$minimal1, $minimal2, $minimal3];

    my $equality_checker = method : int ($object1 : object, $object2 : object) {
      my $minimal1 = (TestCase::Minimal)$object1;
      my $minimal2 = (TestCase::Minimal)$object2;

      if ($minimal1 == $minimal2) {
        return 1;
      }
      else {
        return 0;
      }
    };

    {
      my $is_equals = Fn->equals_array_object($nums1, $nums2, $equality_checker);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_object($nums1, $nums3, $equality_checker);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_object($nums1, $nums4, $equality_checker);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = Fn->equals_array_object($nums1, $nums5, $equality_checker);
      unless ($is_equals) {
        return 0;
      }
    }

    return 1;
  }

  static method new_array_proto : int () {
    my $minimals = new TestCase::Minimal[1];

    my $new_array_object = Fn->new_array_proto($minimals, 2);
    unless ($new_array_object isa TestCase::Minimal[]) {
      return 0;
    }
    my $new_minimals = (TestCase::Minimal[])$new_array_object;
    unless (@$new_minimals == 2) {
      return 0;
    }

    return 1;
  }
  static method copy_array_range_byte : int () {
    {
      my $nums = [(byte)5, -7, 9, Fn->INT8_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_byte($nums, 0, 7);
      unless (Fn->equals_array_byte($range, [(byte)5, -7, 9, Fn->INT8_MIN(), 127, 15, 19])) {
        return 0;
      }
    }

    {
      my $nums = [(byte)5, -7, 9, Fn->INT8_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_byte($nums, 1, 3);
      unless (Fn->equals_array_byte($range, [(byte)-7, 9, Fn->INT8_MIN()])) {
        return 0;
      }
    }
    
    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_byte(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_byte([(byte)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_byte([(byte)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_byte([(byte)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }
  static method copy_array_range_short : int () {
    {
      my $nums = [(short)5, -7, 9, Fn->INT16_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_short($nums, 0, 7);
      unless (Fn->equals_array_short($range, [(short)5, -7, 9, Fn->INT16_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(short)5, -7, 9, Fn->INT16_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_short($nums, 1, 3);
      unless (Fn->equals_array_short($range, [(short)-7, 9, Fn->INT16_MIN()])) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_short(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_short([(short)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_short([(short)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_short([(short)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }
  static method copy_array_range_int : int () {
    {
      my $nums = [(int)5, -7, 9, Fn->INT32_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_int($nums, 0, 7);
      unless (Fn->equals_array_int($range, [(int)5, -7, 9, Fn->INT32_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(int)5, -7, 9, Fn->INT32_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_int($nums, 1, 3);
      unless (Fn->equals_array_int($range, [(int)-7, 9, Fn->INT32_MIN()])) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_int(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_int([(int)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_int([(int)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_int([(int)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }
  static method copy_array_range_long : int () {
    {
      my $nums = [(long)5, -7, 9, Fn->INT64_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_long($nums, 0, 7);
      unless (Fn->equals_array_long($range, [(long)5, -7, 9, Fn->INT64_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(long)5, -7, 9, Fn->INT64_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_long($nums, 1, 3);
      unless (Fn->equals_array_long($range, [(long)-7, 9, Fn->INT64_MIN()])) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_long(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_long([(long)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_long([(long)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_long([(long)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }
  static method copy_array_range_float : int () {
    {
      my $nums = [(float)5, -7, 9, Fn->FLT_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_float($nums, 0, 7);
      unless (Fn->equals_array_float($range, [(float)5, -7, 9, Fn->FLT_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(float)5, -7, 9, Fn->FLT_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_float($nums, 1, 3);
      unless (Fn->equals_array_float($range, [(float)-7, 9, Fn->FLT_MIN()])) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_float(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_float([(float)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_float([(float)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_float([(float)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }
  
  static method copy_array_range_double : int () {
    {
      my $nums = [(double)5, -7, 9, Fn->DBL_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_double($nums, 0, 7);
      unless (Fn->equals_array_double($range, [(double)5, -7, 9, Fn->DBL_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(double)5, -7, 9, Fn->DBL_MIN(), 127, 15, 19];
      my $range = Fn->copy_array_range_double($nums, 1, 3);
      unless (Fn->equals_array_double($range, [(double)-7, 9, Fn->DBL_MIN()])) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_double(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_double([(double)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_double([(double)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_double([(double)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }

  static method copy_array_range_string : int () {
    {
      my $strings = ["a", "b", "c", "d", "e", "f", "g"];
      my $range = Fn->copy_array_range_string($strings, 0, 7);
      unless (Fn->equals_array_string($range, ["a", "b", "c", "d", "e", "f", "g"])) {
        return 0;
      }
    }
    {
      my $strings = ["a", "b", "c", "d", "e", "f", "g"];
      my $range = Fn->copy_array_range_string($strings, 1, 3);
      unless (Fn->equals_array_string($range, ["b", "c", "d"])) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_string(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      {
        eval { Fn->copy_array_range_string([(string)5, -7, 9], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_string([(string)5, -7, 9], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        eval { Fn->copy_array_range_string([(string)5, -7, 9], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }

  static method copy_array_range_object : int () {

    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      my $minimal4 = TestCase::Minimal->new;

      my $elems = [$minimal1, $minimal2, $minimal3, $minimal4];
      my $range = (TestCase::Minimal[])Fn->copy_array_range_object($elems, 0, 4);
      unless (Fn->equals_array_object($range, [$minimal1, $minimal2, $minimal3, $minimal4], EqualityChecker::SameObject->new)) {
        return 0;
      }
    }
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      my $minimal4 = TestCase::Minimal->new;

      my $elems = [$minimal1, $minimal2, $minimal3, $minimal4];
      my $range = (TestCase::Minimal[])Fn->copy_array_range_object($elems, 1, 2);
      unless (Fn->equals_array_object($range, [$minimal2, $minimal3], EqualityChecker::SameObject->new)) {
        return 0;
      }
    }

    # Exception - The argument array must be defined
    {
      eval { Fn->copy_array_range_object(undef, 0, 7); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be in the array range
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      {
        eval { Fn->copy_array_range_object([$minimal1, $minimal2, $minimal3], -1, 1); };
        unless ($@) {
          return 0;
        }
      }
      {
        eval { Fn->copy_array_range_object([$minimal1, $minimal2, $minimal3], 3, 1); };
        unless ($@) {
          return 0;
        }
      }
    }

    # Exception - Offset + length must be in the array range
    {
      {
        my $minimal1 = TestCase::Minimal->new;
        my $minimal2 = TestCase::Minimal->new;
        my $minimal3 = TestCase::Minimal->new;
        
        eval { Fn->copy_array_range_object([$minimal1, $minimal2, $minimal3], 1, 3); };
        unless ($@) {
          return 0;
        }
      }
    }

    return 1;
  }

  static method memcpy_byte : int () {
    
    # Copy
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      Fn->memcpy_byte($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_byte($dest, [(byte)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      Fn->memcpy_byte($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_byte($dest, [(byte)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5, 9];
      Fn->memcpy_byte($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_byte($dest, [(byte)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      Fn->memcpy_byte($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_byte($dest, [(byte)0, 0, 0, 0])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(byte)1, 3, 5];
      eval { Fn->memcpy_byte(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new byte[4];
      eval { Fn->memcpy_byte($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      eval { Fn->memcpy_byte($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      eval { Fn->memcpy_byte($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      eval { Fn->memcpy_byte($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memcpy_short : int () {
    
    # Copy
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      Fn->memcpy_short($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_short($dest, [(short)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      Fn->memcpy_short($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_short($dest, [(short)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5, 9];
      Fn->memcpy_short($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_short($dest, [(short)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      Fn->memcpy_short($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_short($dest, [(short)0, 0, 0, 0])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(short)1, 3, 5];
      eval { Fn->memcpy_short(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new short[4];
      eval { Fn->memcpy_short($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      eval { Fn->memcpy_short($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      eval { Fn->memcpy_short($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      eval { Fn->memcpy_short($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memcpy_int : int () {
    
    # Copy
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      Fn->memcpy_int($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_int($dest, [(int)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      Fn->memcpy_int($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_int($dest, [(int)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5, 9];
      Fn->memcpy_int($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_int($dest, [(int)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      Fn->memcpy_int($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_int($dest, [(int)0, 0, 0, 0])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(int)1, 3, 5];
      eval { Fn->memcpy_int(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new int[4];
      eval { Fn->memcpy_int($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      eval { Fn->memcpy_int($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      eval { Fn->memcpy_int($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      eval { Fn->memcpy_int($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memcpy_long : int () {
    
    # Copy
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      Fn->memcpy_long($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_long($dest, [(long)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      Fn->memcpy_long($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_long($dest, [(long)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5, 9];
      Fn->memcpy_long($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_long($dest, [(long)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      Fn->memcpy_long($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_long($dest, [(long)0, 0, 0, 0])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(long)1, 3, 5];
      eval { Fn->memcpy_long(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new long[4];
      eval { Fn->memcpy_long($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      eval { Fn->memcpy_long($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      eval { Fn->memcpy_long($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      eval { Fn->memcpy_long($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memcpy_float : int () {
    
    # Copy
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      Fn->memcpy_float($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_float($dest, [(float)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      Fn->memcpy_float($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_float($dest, [(float)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5, 9];
      Fn->memcpy_float($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_float($dest, [(float)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      Fn->memcpy_float($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_float($dest, [(float)0, 0, 0, 0])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(float)1, 3, 5];
      eval { Fn->memcpy_float(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new float[4];
      eval { Fn->memcpy_float($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      eval { Fn->memcpy_float($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      eval { Fn->memcpy_float($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      eval { Fn->memcpy_float($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memcpy_double : int () {
    
    # Copy
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      Fn->memcpy_double($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_double($dest, [(double)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      Fn->memcpy_double($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_double($dest, [(double)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5, 9];
      Fn->memcpy_double($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_double($dest, [(double)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      Fn->memcpy_double($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_double($dest, [(double)0, 0, 0, 0])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(double)1, 3, 5];
      eval { Fn->memcpy_double(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new double[4];
      eval { Fn->memcpy_double($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      eval { Fn->memcpy_double($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      eval { Fn->memcpy_double($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      eval { Fn->memcpy_double($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memmove_byte : int () {
    
    # Copy
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      Fn->memmove_byte($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_byte($dest, [(byte)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      Fn->memmove_byte($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_byte($dest, [(byte)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5, 9];
      Fn->memmove_byte($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_byte($dest, [(byte)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      Fn->memmove_byte($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_byte($dest, [(byte)0, 0, 0, 0])) {
        return 0;
      }
    }
    
    # Copy overwrap
    {
      my $dest = [(byte)1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      Fn->memmove_byte($dest, 0, $dest, 1, 9);
      unless (Fn->equals_array_byte($dest, [(byte)2, 3, 4, 5, 6, 7, 8, 9, 10, 10])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(byte)1, 3, 5];
      eval { Fn->memmove_byte(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new byte[4];
      eval { Fn->memmove_byte($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      eval { Fn->memmove_byte($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      eval { Fn->memmove_byte($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new byte[4];
      my $source = [(byte)1, 3, 5];
      eval { Fn->memmove_byte($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memmove_short : int () {
    
    # Copy
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      Fn->memmove_short($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_short($dest, [(short)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      Fn->memmove_short($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_short($dest, [(short)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5, 9];
      Fn->memmove_short($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_short($dest, [(short)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      Fn->memmove_short($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_short($dest, [(short)0, 0, 0, 0])) {
        return 0;
      }
    }
    
    # Copy overwrap
    {
      my $dest = [(short)1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      Fn->memmove_short($dest, 0, $dest, 1, 9);
      unless (Fn->equals_array_short($dest, [(short)2, 3, 4, 5, 6, 7, 8, 9, 10, 10])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(short)1, 3, 5];
      eval { Fn->memmove_short(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new short[4];
      eval { Fn->memmove_short($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      eval { Fn->memmove_short($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      eval { Fn->memmove_short($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new short[4];
      my $source = [(short)1, 3, 5];
      eval { Fn->memmove_short($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memmove_int : int () {
    
    # Copy
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      Fn->memmove_int($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_int($dest, [(int)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      Fn->memmove_int($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_int($dest, [(int)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5, 9];
      Fn->memmove_int($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_int($dest, [(int)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      Fn->memmove_int($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_int($dest, [(int)0, 0, 0, 0])) {
        return 0;
      }
    }
    
    # Copy overwrap
    {
      my $dest = [(int)1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      Fn->memmove_int($dest, 0, $dest, 1, 9);
      unless (Fn->equals_array_int($dest, [(int)2, 3, 4, 5, 6, 7, 8, 9, 10, 10])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(int)1, 3, 5];
      eval { Fn->memmove_int(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new int[4];
      eval { Fn->memmove_int($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      eval { Fn->memmove_int($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      eval { Fn->memmove_int($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new int[4];
      my $source = [(int)1, 3, 5];
      eval { Fn->memmove_int($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memmove_long : int () {
    
    # Copy
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      Fn->memmove_long($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_long($dest, [(long)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      Fn->memmove_long($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_long($dest, [(long)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5, 9];
      Fn->memmove_long($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_long($dest, [(long)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      Fn->memmove_long($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_long($dest, [(long)0, 0, 0, 0])) {
        return 0;
      }
    }
    
    # Copy overwrap
    {
      my $dest = [(long)1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      Fn->memmove_long($dest, 0, $dest, 1, 9);
      unless (Fn->equals_array_long($dest, [(long)2, 3, 4, 5, 6, 7, 8, 9, 10, 10])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(long)1, 3, 5];
      eval { Fn->memmove_long(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new long[4];
      eval { Fn->memmove_long($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      eval { Fn->memmove_long($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      eval { Fn->memmove_long($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new long[4];
      my $source = [(long)1, 3, 5];
      eval { Fn->memmove_long($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memmove_float : int () {
    
    # Copy
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      Fn->memmove_float($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_float($dest, [(float)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      Fn->memmove_float($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_float($dest, [(float)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5, 9];
      Fn->memmove_float($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_float($dest, [(float)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      Fn->memmove_float($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_float($dest, [(float)0, 0, 0, 0])) {
        return 0;
      }
    }
    
    # Copy overwrap
    {
      my $dest = [(float)1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      Fn->memmove_float($dest, 0, $dest, 1, 9);
      unless (Fn->equals_array_float($dest, [(float)2, 3, 4, 5, 6, 7, 8, 9, 10, 10])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(float)1, 3, 5];
      eval { Fn->memmove_float(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new float[4];
      eval { Fn->memmove_float($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      eval { Fn->memmove_float($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      eval { Fn->memmove_float($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new float[4];
      my $source = [(float)1, 3, 5];
      eval { Fn->memmove_float($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method memmove_double : int () {
    
    # Copy
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      Fn->memmove_double($dest, 0, $source, 0, 3);
      unless (Fn->equals_array_double($dest, [(double)1, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with offset
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      Fn->memmove_double($dest, 1, $source, 0, 3);
      unless (Fn->equals_array_double($dest, [(double)0, 1, 3, 5])) {
        return 0;
      }
    }

    # Copy with offset and length
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5, 9];
      Fn->memmove_double($dest, 1, $source, 1, 2);
      unless (Fn->equals_array_double($dest, [(double)0, 3, 5, 0])) {
        return 0;
      }
    }

    # Copy with 0 length
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      Fn->memmove_double($dest, 0, $source, 0, 0);
      unless (Fn->equals_array_double($dest, [(double)0, 0, 0, 0])) {
        return 0;
      }
    }
    
    # Copy overwrap
    {
      my $dest = [(double)1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      Fn->memmove_double($dest, 0, $dest, 1, 9);
      unless (Fn->equals_array_double($dest, [(double)2, 3, 4, 5, 6, 7, 8, 9, 10, 10])) {
        return 0;
      }
    }

    # Exception - Destnation must be defined
    {
      my $source = [(double)1, 3, 5];
      eval { Fn->memmove_double(undef, 0, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source must be defined
    {
      my $dest = new double[4];
      eval { Fn->memmove_double($dest, 0, undef, 0, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Length must be more than or equals to 0
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      eval { Fn->memmove_double($dest, 0, $source, 0, -1); };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Destnation offset + length must be within the range of the destnation array
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      eval { Fn->memmove_double($dest, 2, $source, 0, 3); };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Source offset + length must be within the range of the source array
    {
      my $dest = new double[4];
      my $source = [(double)1, 3, 5];
      eval { Fn->memmove_double($dest, 0, $source, 1, 3); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }
}