static UWildcard create(Kind kind, @Nullable UTree<?> bound) {
    checkArgument(BOUND_KINDS.containsKey(kind));
    // verify bound is null iff kind is UNBOUNDED_WILDCARD
    checkArgument((bound == null) == (kind == Kind.UNBOUNDED_WILDCARD));
    return new AutoValue_UWildcard(kind, bound);
  }
@Test
  public void equality() {
    UExpression objectIdent = UClassIdent.create("java.lang.Object");
    UExpression setIdent = UTypeApply.create("java.util.Set", objectIdent);

    new EqualsTester()
        .addEqualityGroup(UWildcard.create(Kind.UNBOUNDED_WILDCARD, null))
        .addEqualityGroup(UWildcard.create(Kind.EXTENDS_WILDCARD, objectIdent))
        .addEqualityGroup(UWildcard.create(Kind.EXTENDS_WILDCARD, setIdent))
        // ? extends Set<Object>
        .addEqualityGroup(UWildcard.create(Kind.SUPER_WILDCARD, setIdent))
        // ? super Set<Object>
        .testEquals();
  }