for @markhibberd: GROOVY-4655: groovy.transform.EqualsAndHashCode annotation does not handle cycles (fix hashCode() too)