private ConcreteType maybeAddAutoboxes(ConcreteType cType, JSType jsType, String prop) {
      jsType = jsType.restrictByNotNullOrUndefined();
      if (jsType instanceof UnionType) {
        for (JSType alt : ((UnionType) jsType).getAlternates()) {
          return maybeAddAutoboxes(cType, alt, prop);
        }
      }

      if (jsType.autoboxesTo() != null) {
        JSType autoboxed = jsType.autoboxesTo();
        return cType.unionWith(tt.getConcreteInstance((ObjectType) autoboxed));
      } else if (jsType.unboxesTo() != null) {
        return cType.unionWith(tt.getConcreteInstance((ObjectType) jsType));
      }

      return cType;
    }
    @Override
    public ObjectType getTypeWithProperty(String field, JSType type) {
      if (!(type instanceof ObjectType)) {
        if (type.autoboxesTo() != null) {
          type = type.autoboxesTo();
        } else {
          return null;
        }
      }

      // Ignore the prototype itself at all times.
      if ("prototype".equals(field)) {
        return null;
      }

      // We look up the prototype chain to find the highest place (if any) that
      // this appears.  This will make references to overriden properties look
      // like references to the initial property, so they are renamed alike.
      ObjectType foundType = null;
      ObjectType objType = ObjectType.cast(type);
      while (objType != null && objType.getImplicitPrototype() != objType) {
        if (objType.hasOwnProperty(field)) {
          foundType = objType;
        }
        objType = objType.getImplicitPrototype();
      }
      // If the property does not exist on the referenced type but the original
      // type is an object type, see if any subtype has the property.
      if (foundType == null) {
        ObjectType maybeType =
            ObjectType.cast(registry.getGreatestSubtypeWithProperty(type, field));
        // getGreatestSubtypeWithProperty does not guarantee that the property
        // is defined on the returned type, it just indicates that it might be,
        // so we have to double check.
        if (maybeType != null && maybeType.hasOwnProperty(field)) {
          foundType = maybeType;
        }
      }
      return foundType;
    }
 @Override
 public boolean isTypeToSkip(JSType type) {
   return type.isEnumType() || (type.autoboxesTo() != null);
 }