Неожиданное поведение с перегруженными методами

Я немного озадачен поведением перегрузки метода groovys: учитывая класс и тесты ниже, я довольно хорошо сtestAStringNull а такжеtestBStringNull бросая неоднозначные исключения вызова метода, но почему это не так для testANull а такжеtestBNull затем?

И, что гораздо важнее: почемуtestBNull(null) вызовString foo(A arg)? Я предполагаю, что объект не знает о типе переменной, к которой он привязан, но почему этот вызов не является двусмысленным для groovy, в то время как другие?

(Надеюсь, я объяснил достаточно хорошо, моя голова болит от создания этого минимального пример.)

class Foo {
    static class A {}
    static class B {}

    String foo(A arg) { return 'a' }

    String foo(String s, A a) { return 'a' }

    String foo(B arg) { return 'b' }

    String foo(String s, B b) { return 'b' }
}

тесты:

import org.junit.Test
import Foo.A
import Foo.B

class FooTest {
    Foo foo = new Foo()

    @Test
    void testA() {
        A a = new A()
        assert foo.foo(a) == 'a'
    }

    @Test
    void testAString() {
        A a = new A()
        assert foo.foo('foo', a) == 'a'
    }

    @Test()
    void testANull() {
        A a = null
        assert foo.foo(a) == 'a'
    }

    @Test
    void testAStringNull() {
        A a = null
        assert foo.foo('foo', a) == 'a'
    }

    @Test
    void testB() {
        B b = new B()
        assert foo.foo(b) == 'b'
    }

    @Test
    void testBString() {
        B b = new B()
        assert foo.foo('foo', b) == 'b'
    }

    @Test
    void testBNull() {
        B b = null
        assert foo.foo(b) == 'b'
    }

    @Test
    void testBStringNull() {
        B b = null
        assert foo.foo('foo', b) == 'b'
    }

}