public static List<ClosedPatternRowObject> mineClosedPatterns(
			List<ByteSequenceRowObject> byteSeqRowObjects, double minPercentage, int minFixedBits,
			boolean useBinary, PatternType type, ContextRegisterFilter cRegFilter,
			Component parent) {
		List<Sequence> seqsToMine = new ArrayList<>();
		for (ByteSequenceRowObject byteSeqRowObject : byteSeqRowObjects) {
			String seq = byteSeqRowObject.getSequence();
			Integer count = byteSeqRowObject.getNumOccurrences();
			if (useBinary) {
				StringBuilder paddedString = new StringBuilder();
				for (int i = 0; i < seq.length(); ++i) {
					String currentChar = seq.substring(i, i + 1);
					String unpaddedChar = Integer.toBinaryString(Integer.parseInt(currentChar, 16));
					StringBuilder paddedChar = new StringBuilder();
					switch (unpaddedChar.length()) {
						case 1:
							paddedChar.append("000");
							break;
						case 2:
							paddedChar.append("00");
							break;
						case 3:
							paddedChar.append("0");
							break;
						case 4:
							break;
						default:
							Msg.info(ClosedPatternRowObject.class,
								"Shouldn't happen, unpaddedString = " + unpaddedChar);
					}
					paddedString.append(paddedChar);
					paddedString.append(unpaddedChar);
				}
				seq = paddedString.toString();
			}
			seqsToMine.add(new Sequence(seq, count));
		}
		int length = byteSeqRowObjects.get(0).getSequence().length();
		if (useBinary) {
			length = 4 * length;
		}

		SequenceDatabase database = new SequenceDatabase(seqsToMine, length);

		int minSupport = (int) (database.getTotalNumSeqs() * minPercentage);
		ClosedSequenceMiner miner = new ClosedSequenceMiner(database, minSupport);
		Set<FrequentSequence> closedSeqs = null;
		//for testing
		if (parent == null) {
			closedSeqs = miner.mineClosedSequences(TaskMonitor.DUMMY);
		}
		else {
			MineSequenceTask mineTask = new MineSequenceTask(miner);
			@SuppressWarnings("unused")
			TaskLauncher launcher = new TaskLauncher(mineTask, parent);
			closedSeqs = mineTask.getClosedSeqs();
		}

		List<ClosedPatternRowObject> rowObjects = new ArrayList<ClosedPatternRowObject>();
		int totalNumSeqs = database.getTotalNumSeqs();
		for (FrequentSequence seq : closedSeqs) {
			ClosedPatternRowObject rowObject = createClosedPatternRowObject(seq.getSequence(),
				seq.getSupport(), totalNumSeqs, useBinary, length, type, cRegFilter);
			if (rowObject.getNumFixedBits() >= minFixedBits) {
				rowObjects.add(rowObject);
			}
		}
		Msg.info(ClosedPatternRowObject.class, "\nFound " + closedSeqs.size() + " patterns");
		return rowObjects;
	}
Mine closed patterns from the byte sequences.

@param byteSeqRowObjects byte sequences to mine
@param minPercentage minimum percentage of byte sequences that a pattern should be in
@param minFixedBits minimum number of fixed bits that a pattern should contain
@param useBinary whether to consider the sequences as binary sequences or character sequences
@param type pattern type of row objects
@param cRegFilter context register filter used when gathering row objects (can be {@code null})
@param parent Component parent for the Task Dialog (can be {@code null})
@return closed sequences
Ghidra/Features/BytePatterns/src/main/java/ghidra/bitpatterns/gui/ClosedPatternRowObject.java