@Override
 protected WildcardTypeReference doCopyInto(ITypeReferenceOwner owner) {
   WildcardTypeReference result = owner.newWildcardTypeReference();
   if (upperBounds != null && !upperBounds.isEmpty()) {
     for (LightweightTypeReference upperBound : upperBounds) {
       LightweightTypeReference copiedUpperBound =
           upperBound.copyInto(owner).getInvariantBoundSubstitute();
       if (!(copiedUpperBound.isPrimitive() || copiedUpperBound.isPrimitiveVoid())) {
         result.addUpperBound(copiedUpperBound);
       }
     }
   }
   if (lowerBound != null) {
     LightweightTypeReference copiedLowerBound =
         lowerBound.copyInto(owner).getInvariantBoundSubstitute();
     if (!(copiedLowerBound.isPrimitive() || copiedLowerBound.isPrimitiveVoid())) {
       result.setLowerBound(copiedLowerBound);
     }
   }
   return result;
 }
 public void addUpperBound(LightweightTypeReference upperBound) {
   if (upperBound == null) {
     throw new NullPointerException("upperBound may not be null");
   }
   if (!upperBound.isOwnedBy(getOwner())) {
     throw new IllegalArgumentException("upperBound is not valid in current context");
   }
   if (upperBound instanceof WildcardTypeReference) {
     throw new IllegalArgumentException("Wildcards are not supported as upper bounds");
   }
   if (upperBound.isPrimitive() || upperBound.isPrimitiveVoid()) {
     throw new IllegalArgumentException("Constraints may not be primitives");
   }
   if (upperBounds == null) upperBounds = Lists.newArrayListWithCapacity(2);
   upperBounds.add(upperBound);
   resolved = resolved && upperBound.isResolved();
 }
  public void setLowerBound(LightweightTypeReference lowerBound) {
    if (lowerBound == null) {
      throw new NullPointerException("lowerBound may not be null");
    }
    if (!lowerBound.isOwnedBy(getOwner())) {
      throw new IllegalArgumentException("lowerBound is not valid in current context");
    }
    if (lowerBound instanceof WildcardTypeReference) {
      throw new IllegalArgumentException("Wildcards are not supported as lower bounds");
    }
    if (lowerBound.isPrimitive() || lowerBound.isPrimitiveVoid()) {
      throw new IllegalArgumentException("Constraints may not be primitives");
    }
    if (this.lowerBound != null && this.lowerBound != lowerBound) {
      throw new IllegalStateException("only one lower bound is supported");
    }

    this.lowerBound = lowerBound;
    resolved = resolved && lowerBound.isResolved();
  }