@Nonnull
	static IntermediateMappings parse(@Nonnull String mappingText, @Nonnull MappingTreeReader visitor) throws InvalidMappingException {
		// Populate the mapping-io model
		MemoryMappingTree tree = new MemoryMappingTree();
		StringReader reader = new StringReader(mappingText);
		try {
			visitor.read(reader, tree);
		} catch (IOException ex) {
			throw new InvalidMappingException(ex);
		}

		// Create our mapping model.
		IntermediateMappings mappings = new IntermediateMappings();

		// Mapping IO supports multiple namespaces for outputs.
		// This is only really used in the 'tiny' format. Generally speaking the input columns look like:
		//   obfuscated, intermediate, clean
		// or:
		//   intermediate, clean
		// We want everything to map to the final column, rather than their notion of the first
		// column mapping to one of the following columns.
		int namespaceCount = tree.getDstNamespaces().size();
		int finalNamespace = namespaceCount - 1;
		for (MappingTree.ClassMapping cm : tree.getClasses()) {
			String finalClassName = cm.getDstName(finalNamespace);
			if (finalClassName != null) {
				// Add the base case: input --> final output name
				mappings.addClass(cm.getSrcName(), finalClassName);

				// Add destination[n] --> final output name, where n < destinations.length - 1.
				// This is how we handle cases like 'intermediate --> clean' despite both of those
				// being "output" columns.
				if (namespaceCount > 1)
					for (int i = 0; i < finalNamespace; i++) {
						String intermediateClassName = cm.getDstName(i);
						if (intermediateClassName != null)
							mappings.addClass(intermediateClassName, finalClassName);
					}
			}

			for (MappingTree.FieldMapping fm : cm.getFields()) {
				String finalFieldName = fm.getDstName(finalNamespace);
				if (finalFieldName == null)
					continue;

				// Base case, like before.
				String fieldDesc = fm.getSrcDesc();
				mappings.addField(cm.getSrcName(), fieldDesc, fm.getSrcName(), finalFieldName);

				// Support extra namespaces, like before.
				if (namespaceCount > 1)
					for (int i = 0; i < finalNamespace; i++) {
						String intermediateClassName = cm.getDstName(i);
						String intermediateFieldDesc = fm.getDstDesc(i);
						String intermediateFieldName = fm.getDstName(i);
						if (intermediateClassName != null && intermediateFieldName != null)
							mappings.addField(intermediateClassName, intermediateFieldDesc, intermediateFieldName, finalFieldName);
					}
			}

			for (MappingTree.MethodMapping mm : cm.getMethods()) {
				String finalMethodName = mm.getDstName(finalNamespace);
				if (finalMethodName == null)
					continue;

				// Base case, like before.
				String methodDesc = mm.getSrcDesc();
				if (methodDesc != null)
					mappings.addMethod(cm.getSrcName(), methodDesc, mm.getSrcName(), finalMethodName);

				// Support extra namespaces, like before.
				if (namespaceCount > 1)
					for (int i = 0; i < finalNamespace; i++) {
						String intermediateClassName = cm.getDstName(i);
						String intermediateMethodDesc = mm.getDstDesc(i);
						String intermediateMethodName = mm.getDstName(i);
						if (intermediateClassName != null && intermediateMethodDesc != null && intermediateMethodName != null)
							mappings.addMethod(intermediateClassName, intermediateMethodDesc, intermediateMethodName, finalMethodName);
					}
			}
		}
		return mappings;
	}
A utility for utilizing mapping-io to parse mapping text formats.

@param mappingText
		Text of mapping to parse.
@param visitor
		Visitor pointing to a mapping-io format reader.

@return Intermediate mapping representation of the parsed text.

@throws InvalidMappingException
		When reading the mappings encounters any failure.
recaf-core/src/main/java/software/coley/recaf/services/mapping/format/MappingFileFormat.java