ArchiveType::Certainty ArchiveType_DAT_Sango::isInstance(stream::input_sptr psArchive) const
{
	stream::pos lenArchive = psArchive->size();

	// TESTED BY: fmt_dat_sango_isinstance_c01
	if (lenArchive < DAT_FAT_ENTRY_LEN) return DefinitelyNo; // too short

	uint32_t offEndFAT;
	psArchive->seekg(0, stream::start);
	psArchive >> u32le(offEndFAT);
	// TESTED BY: fmt_dat_sango_isinstance_c02
	if (offEndFAT > lenArchive) return DefinitelyNo;

	uint32_t offNext = 4; // in case of no files
	for (unsigned int offset = 4; offset < offEndFAT; offset += 4) {
		psArchive >> u32le(offNext);
		// TESTED BY: fmt_dat_sango_isinstance_c03
		if (offNext > lenArchive) return DefinitelyNo;
	}

	// Last offset must equal file size
	// TESTED BY: fmt_dat_sango_isinstance_c04
	if (offNext != lenArchive) return DefinitelyNo;

	// TESTED BY: fmt_dat_sango_isinstance_c00
	return DefinitelyYes;
}
MapType::Certainty MapType_Hocus::isInstance(stream::input_sptr psMap) const
{
	stream::pos lenMap = psMap->size();
	// TESTED BY: fmt_map_hocus_isinstance_c01
	if (lenMap != 14400) return MapType::DefinitelyNo; // wrong size

	// TESTED BY: fmt_map_hocus_isinstance_c00
	return MapType::PossiblyYes;
}
TilesetType_HarryCHR::Certainty TilesetType_HarryCHR::isInstance(
	stream::input_sptr psTileset) const
{
	stream::pos len = psTileset->size();

	// TESTED BY: tls_harry_chr_isinstance_c01
	if (len != CHR_WIDTH * CHR_HEIGHT * CHR_NUM_TILES) return DefinitelyNo; // wrong size

	// TESTED BY: tls_harry_chr_isinstance_c00
	return PossiblyYes;
}
TilesetType_CComic2::Certainty TilesetType_CComic2::isInstance(stream::input_sptr psGraphics) const
{
	stream::pos len = psGraphics->size();
	if (len > 65535) return DefinitelyNo; // file too large (probably)
	psGraphics->seekg(0, stream::start);
	uint16_t num;
	for (int i = 0; i < 3; i++) {
		psGraphics >> u16le(num);
		if (num > 512) return DefinitelyNo; // too many tiles (probably)
	}
	return Unsure;
}
MusicPtr MusicType_INS_AdLib::read(stream::input_sptr input, SuppData& suppData) const
{
	stream::len lenFile = input->size();
	input->seekg(0, stream::start);
	MusicPtr music(new Music());
	music->patches.reset(new PatchBank());

	int op;
	bool wavesel;
	switch (lenFile) {
		case 54:
			op = 1;
			wavesel = true;
			break;
		case 78:
		case 80:
			op = 2;
			wavesel = true;
			break;
		default:
			std::cout << "[ins-adlib] Unknown format variant: length=" << lenFile
				<< std::endl;
			if (lenFile < 74) op = 1; else op = 2;
			wavesel = false;
			break;
	}

	uint16_t unknown;
	input >> u16le(unknown);

	OPLPatchPtr oplPatch(new OPLPatch());
	readAdLibOperator<uint16_t>(input, &oplPatch->m, &oplPatch->feedback, &oplPatch->connection);
	if (op > 1) {
		readAdLibOperator<uint16_t>(input, &oplPatch->c, NULL, NULL);
	}

	std::string title;
	input >> nullPadded(title, INS_TITLE_LEN);
	if (!title.empty()) music->metadata[Metadata::Title] = title;

	if (wavesel) {
		readAdLibWaveSel<uint16_t>(input, &oplPatch->m);
		if (op > 1) {
			readAdLibWaveSel<uint16_t>(input, &oplPatch->c);
		}
	}
	music->patches->push_back(oplPatch);

	return music;
}
ArchiveType::Certainty ArchiveType_EXE_CCaves::isInstance(stream::input_sptr psArchive) const
{
	stream::pos lenArchive = psArchive->size();

	if (lenArchive == 191984) {
		// TESTED BY: TODO fixed_exe_ccaves_isinstance_c00
		psArchive->seekg(0x1E00, stream::start);
		char buffer[8];
		psArchive->read(buffer, 8);
		// Unfortunately no version strings, so check some data I
		// selected at random...
		if (strncmp(buffer, "\x55\x89\xE5\x8B\x46\x06\xBA\xA0", 8) != 0)
			return DefinitelyNo;

		return DefinitelyYes;
	}

	// TESTED BY: TODO (generic)
	return DefinitelyNo;
}
TilesetType_MonsterBashSprite::Certainty TilesetType_MonsterBashSprite::isInstance(
	stream::input_sptr psGraphics) const
{
	stream::len lenRemaining = psGraphics->size();
	psGraphics->seekg(0, stream::start);

	// TESTED BY: tls_bash_sprite_isinstance_c02
	if (lenRemaining < MB_MIN_FILE_LEN) return DefinitelyNo;

	uint8_t sig;
	psGraphics >> u8(sig);
	lenRemaining--;

	// TESTED BY: tls_bash_sprite_isinstance_c03
	if (sig != 0xFF) return DefinitelyNo;

	while (lenRemaining >= MB_SPR_EFAT_ENTRY_LEN) {
		uint16_t lenBlock;
		psGraphics >> u16le(lenBlock);
		lenRemaining -= 2;

		// TESTED BY: tls_bash_sprite_isinstance_c04
		if (lenBlock < MB_MIN_IMAGE_LEN) return DefinitelyNo;

		// TESTED BY: tls_bash_sprite_isinstance_c05
		if (lenBlock > lenRemaining) return DefinitelyNo;

		psGraphics->seekg(lenBlock - 1, stream::cur);
		uint8_t lastByte;
		psGraphics >> u8(lastByte);
		// TESTED BY: tls_bash_sprite_isinstance_c06
		if (lastByte != 0x00) return DefinitelyNo;

		lenRemaining -= lenBlock;
	}

	// TESTED BY: tls_bash_sprite_isinstance_c00
	// TESTED BY: tls_bash_sprite_isinstance_c01
	return DefinitelyYes;
}
TilesetType_Zone66::Certainty TilesetType_Zone66::isInstance(
	stream::input_sptr psTileset) const
{
	stream::pos len = psTileset->size();
	// TESTED BY: tls_zone66_isinstance_c04
	if (len < Z66_FIRST_TILE_OFFSET) return DefinitelyNo; // too short

	psTileset->seekg(0, stream::start);
	uint32_t numFiles;
	psTileset >> u32le(numFiles);

	if ((numFiles == 0) && (len > 8)) return DefinitelyNo; // invalid empty file

	uint32_t offset, lastOffset = 0;
	for (unsigned int i = 0; i < numFiles; i++) {
		psTileset >> u32le(offset);

		// The first file always starts at offset 0.
		// TESTED BY: tls_zone66_isinstance_c01
		if ((i == 0) && (offset != 0)) return DefinitelyNo;

		// Make sure the offsets are increasing, otherwise we'd get a negative
		// file size (or the file has been tweaked to make opening difficult, but
		// then there's the -f option to gametls for that.)
		// TESTED BY: tls_zone66_isinstance_c02
		if (offset < lastOffset) return DefinitelyNo;

		// Make sure the tile is contained within the file
		// TESTED BY: tls_zone66_isinstance_c03
		if ((numFiles+1) * 4 + offset > len) return DefinitelyNo;

		lastOffset = offset;
	}

	// TESTED BY: tls_zone66_isinstance_c00
	return DefinitelyYes;
}
MusicType::Certainty MusicType_INS_AdLib::isInstance(stream::input_sptr psMusic) const
{
	stream::len lenFile = psMusic->size();
	psMusic->seekg(0, stream::start);

	// Unknown length
	// TESTED BY: ins_ins_adlib_isinstance_c01
	if (
		(lenFile != 54)
		&& (lenFile != 78)
		&& (lenFile != 80)
	) return MusicType::DefinitelyNo;

	for (unsigned int i = 0; i < 14; i++) {
		uint16_t next;
		psMusic >> u16le(next);
		// Out of range value
		// TESTED BY: ins_ins_adlib_isinstance_c02
		if (next > 255) return MusicType::DefinitelyNo;
	}

	// TESTED BY: ins_ins_adlib_isinstance_c00
	return MusicType::PossiblyYes;
}
TilesetType_CComic::Certainty TilesetType_CComic::isInstance(stream::input_sptr psGraphics) const
{
	stream::pos len = psGraphics->size();
	if (len % 128 == 4) return PossiblyYes;
	return DefinitelyNo;
}
CComicSpriteType::Certainty CComicSpriteType::isInstance(stream::input_sptr psGraphics) const
{
	stream::pos len = psGraphics->size();
	if (len % 160 == 0) return PossiblyYes;
	return DefinitelyNo;
}