public TypeProgramInterface parse(AbstractPdb pdb)
			throws IOException, PdbException, CancelledException {
		TypeProgramInterface typeProgramInterface;

		int versionNumberSize = TypeProgramInterface.getVersionNumberSize();
		int streamNumber = getStreamNumber();
		PdbByteReader reader =
			pdb.getReaderForStreamNumber(streamNumber, 0, versionNumberSize);
		if (reader.getLimit() < versionNumberSize) {
			return null;
		}

		int versionNumber = TypeProgramInterface.deserializeVersionNumber(reader);

		// TODO: we do not know where the line should be drawn for each of these
		//  AbstractTypeProgramInterface instantiations.  Had a TI50_ID that was not an 800
		//  instead of a 500.  Also believe that TI42_ID was seen to have 500.  Rest is guess
		//  until we can validate with real data.
		switch (versionNumber) {
			case TI20_ID:
			case TI40_ID:
			case TI41_ID:
				typeProgramInterface =
					new TypeProgramInterface200(pdb, getCategory(), streamNumber);
				break;
			case TI42_ID:
			case TI50DEP_ID:
				typeProgramInterface =
					new TypeProgramInterface500(pdb, getCategory(), streamNumber);
				break;
			case TI50_ID:
			case TI70_ID:
			case TI80_ID:
				typeProgramInterface =
					new TypeProgramInterface800(pdb, getCategory(), streamNumber);
				break;
			default:
				// See MSFT "doc" pdb.cpp OpenIpi() note regarding hack.
				// For IPI, if normal stream number exists and it is unnamed, then try to
				//  parse it, and accept it if no errors.  However, at this point, this would
				//  be considered an error here.  But we want to be careful about killing
				//  PDB parsing here for this case.  So we have added the isReasonableError()
				//  check here, which always returns true for TPI, but does special checking
				//  for IPI.  If IPI says it is not a reasonable error (version number looks like
				//  a non-version number and it is an API), then we must presume that the stream
				//  is not really an IPI stream and just return null.
				if (isReasonableError(versionNumber)) {
					throw new PdbException("Unknown TPI Version: " + versionNumber);
				}
				typeProgramInterface = null;
		}

		return typeProgramInterface;
	}
Parses information to determine the version of {@link TypeProgramInterface} to
 create
@param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
@return the appropriate {@link TypeProgramInterface} or null if the stream does
 not have enough information to be parsed
@throws IOException on file seek or read, invalid parameters, bad file configuration, or
 inability to read required bytes
@throws PdbException upon error in processing components
@throws CancelledException upon user cancellation
Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterfaceParser.java