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;
    }
    /**
     * Add concrete types for autoboxing types if necessary. The concrete type system does not track
     * native types, like string, so add them if they are present in the JSType for the node.
     */
    private ConcreteType maybeAddAutoboxes(ConcreteType cType, Node node, String prop) {
      JSType jsType = node.getJSType();
      if (jsType == null) {
        return cType;
      } else if (jsType.isUnknownType()) {
        for (JSTypeNative nativeType : nativeTypes) {
          ConcreteType concrete =
              tt.getConcreteInstance(tt.getTypeRegistry().getNativeObjectType(nativeType));
          if (concrete != null && !concrete.getPropertyType(prop).isNone()) {
            cType = cType.unionWith(concrete);
          }
        }
        return cType;
      }

      return maybeAddAutoboxes(cType, jsType, prop);
    }
 @Override
 public ConcreteType getType(StaticScope<ConcreteType> scope, Node node, String prop) {
   if (scope != null) {
     ConcreteType c = tt.inferConcreteType((TightenTypes.ConcreteScope) scope, node);
     return maybeAddAutoboxes(c, node, prop);
   } else {
     return null;
   }
 }
 @Override
 public StaticScope<ConcreteType> getFunctionScope(Node decl) {
   ConcreteFunctionType func = tt.getConcreteFunction(decl);
   return (func != null) ? func.getScope() : (StaticScope<ConcreteType>) null;
 }
 @Override
 public StaticScope<ConcreteType> getRootScope() {
   return tt.getTopScope();
 }