return new Stream(location, className, "java.io.InputStream", isUninteresting);
return new Stream(location, className, "java.io.InputStream", isUninteresting, true);
	public Stream isResourceCreation(BasicBlock basicBlock, InstructionHandle handle,		ConstantPoolGen cpg) {		Instruction ins = handle.getInstruction();		Location location = new Location(handle, basicBlock);		try {			if (ins instanceof NEW) {				NEW newIns = (NEW) ins;				Type type = newIns.getType(cpg);				String sig = type.getSignature();				if (!sig.startsWith("L") || !sig.endsWith(";"))					return null;				// Track any subclass of InputStream, OutputStream, Reader, and Writer				// (but not ByteArray/CharArray/String variants)				String className = sig.substring(1, sig.length() - 1).replace('/', '.');				if (Hierarchy.isSubtype(className, "java.io.InputStream")) {					boolean isUninteresting =						Hierarchy.isSubtype(className, "java.io.ByteArrayInputStream")						|| Hierarchy.isSubtype(className, "java.io.ObjectInputStream");					return new Stream(location, className, "java.io.InputStream", isUninteresting);				} else if (Hierarchy.isSubtype(className, "java.io.OutputStream")) {					boolean isUninteresting =						Hierarchy.isSubtype(className, "java.io.ByteArrayOutputStream")						|| Hierarchy.isSubtype(className, "java.io.ObjectOutputStream");					return new Stream(location, className, "java.io.OutputStream", isUninteresting);				} else if (Hierarchy.isSubtype(className, "java.io.Reader")) {					boolean isUninteresting =						Hierarchy.isSubtype(className, "java.io.StringReader")						|| Hierarchy.isSubtype(className, "java.io.CharArrayReader");					return new Stream(location, className, "java.io.Reader", isUninteresting);				} else if (Hierarchy.isSubtype(className, "java.io.Writer")) {					boolean isUninteresting =						Hierarchy.isSubtype(className, "java.io.StringWriter")						|| Hierarchy.isSubtype(className, "java.io.CharArrayWriter");					return new Stream(location, className, "java.io.Writer", isUninteresting);				}			} else if (ins instanceof INVOKEVIRTUAL) {				// Look for socket input and output streams.				// We don't want to track these, because they don't				// need to be closed as long as the socket is closed.				INVOKEVIRTUAL inv = (INVOKEVIRTUAL) ins;				String className = inv.getClassName(cpg);				if (Hierarchy.isSubtype(className, "java.net.Socket")) {					String methodName = inv.getName(cpg);					String methodSig = inv.getSignature(cpg);					if (FindOpenStream.DEBUG)						System.out.println("Socket call: " + methodName + " : " + methodSig);					if (methodName.equals("getOutputStream")						&& methodSig.endsWith(")Ljava/io/OutputStream;")) {						return new Stream(location, "java.io.OutputStream", "java.io.OutputStream",							true, true);											} else if (methodName.equals("getInputStream")						&& methodSig.endsWith(")Ljava/io/InputStream;")) {						return new Stream(location, "java.io.InputStream", "java.io.InputStream",							true, true);					}				}			} else if (ins instanceof GETSTATIC) {				// Look for System.in, System.out, System.err.				// Streams wrapping these don't need to be closed.				GETSTATIC getstatic = (GETSTATIC) ins;				String className = getstatic.getClassName(cpg);				if (className.equals("java.lang.System")) {					String fieldName = getstatic.getName(cpg);					String fieldSig = getstatic.getSignature(cpg);					if (fieldName.equals("in") && fieldSig.equals("Ljava/io/InputStream;")) {						return new Stream(location, "java.io.InputStream", "java.io.InputStream",							true, true);					} else if ((fieldName.equals("out") || fieldName.equals("err")) &&						fieldSig.equals("Ljava/io/PrintStream;")) {						return new Stream(location, "java.io.PrintStream", "java.io.OutputStream",							true, true);					}				}			}			return null;						} catch (ClassNotFoundException e) {			lookupFailureCallback.reportMissingClass(e);			return null;		}	}