private void updateUnion(long sourceDtID, Union sourceDt, Union destUnion,
			MyIdentityHashMap<Long, DataType> resolvedDataTypes) {

		// NOTE: it is possible for the same destUnion to be updated more than once;
		// therefor we must cleanup any previous obsolete fixups
		removeFixUps(sourceDtID);

// TODO: Preserve timestamp?

		// Remove all the components from the destination union.
		while (destUnion.getNumComponents() > 0) {
			destUnion.delete(0);
		}

		// Set to correct alignment and packing.
		updateAlignment(sourceDt, destUnion);

		DataTypeManager sourceDTM = sourceDt.getDataTypeManager();

		// Add each of the defined components back in.
		for (DataTypeComponent sourceComp : sourceDt.getComponents()) {
			DataType sourceCompDt = sourceComp.getDataType();
			BitFieldDataType bfDt = null;
			String comment = sourceComp.getComment();
			DataType resultCompDt = null;

			if (sourceComp.isBitFieldComponent()) {
				// NOTE: primitive type will be used if unable to resolve base type
				bfDt = (BitFieldDataType) sourceCompDt;
				sourceCompDt = bfDt.getBaseDataType();
				if (sourceCompDt instanceof AbstractIntegerDataType) {
					resultCompDt = sourceCompDt.clone(dtms[RESULT]);
				}
			}

			long sourceCompID = sourceDTM.getID(sourceCompDt);

			// Try to get a mapping of the source data type to a result data type.
			if (resultCompDt == null) {
				resultCompDt = getResolvedComponent(sourceCompID, resolvedDataTypes);
			}

			if (resultCompDt == null) {
				if (!myDtAddedList.contains(Long.valueOf(sourceCompID))) {

					// Not added so should be in result if it wasn't deleted there.
					DataType resultsDt = dtms[RESULT].getDataType(sourceCompID);
					if (resultsDt != null) {
						resultCompDt = resultsDt;
					}
					else {
						// must  have been deleted in LATEST
						// put an entry in RESULT for later fixup if
						// it is in conflict
						FixUpInfo info = new FixUpInfo(sourceDtID, sourceCompID,
							sourceComp.getOrdinal(), sourceComp, resolvedDataTypes);
						fixUpList.add(info);
						fixUpIDSet.add(sourceDtID);
					}
				}
				else {
					// Not added/resolved yet
					// put an entry in RESULT for later fixup
					fixUpList.add(new FixUpInfo(sourceDtID, sourceCompID, sourceComp.getOrdinal(),
						sourceComp, resolvedDataTypes));
					fixUpIDSet.add(sourceDtID);
				}
				if (bfDt != null &&
					(resultCompDt == null || !BitFieldDataType.isValidBaseDataType(resultCompDt))) {
					// use primitive type as fallback (may get fixed-up later)
					resultCompDt = bfDt.getPrimitiveBaseDataType();
				}
			}
			if (resultCompDt != null) {
				if (bfDt != null) {
					// bitfield component in union
					try {
						destUnion.addBitField(resultCompDt, bfDt.getDeclaredBitSize(),
							sourceComp.getFieldName(), comment);
					}
					catch (InvalidDataTypeException e) {
						displayError(destUnion, e);
						// Try again with primitive base type
						DataType primitiveBaseDt = bfDt.getPrimitiveBaseDataType();
						comment = buildDataTypeFailureComment(sourceCompDt, e.getMessage(),
							sourceComp.getComment());
						try {
							destUnion.addBitField(primitiveBaseDt, bfDt.getDeclaredBitSize(),
								sourceComp.getFieldName(), comment);
						}
						catch (InvalidDataTypeException exc) {
							throw new RuntimeException(exc); // unexpected
						}
					}
				}
				else {
					// Normal component in union
					int compLen = resultCompDt.getLength();
					if (compLen <= 0) {
						compLen = sourceComp.getLength();
					}
					try {
						destUnion.add(resultCompDt, compLen, sourceComp.getFieldName(), comment);
					}
					catch (IllegalArgumentException e) {
						comment =
							buildDataTypeFailureComment(sourceCompDt, e.getMessage(), comment);
						destUnion.add(BadDataType.dataType, compLen, sourceComp.getFieldName(),
							comment);
						displayError(destUnion, e);
					}
				}
			}
			else {
				// Add fixup placeholder to prevent the ordinal values and component sizes from 
				// changing.  Nothing we can do about packing which may be affected.
				// These should get fixed-up later.
				destUnion.add(BadDataType.dataType, sourceComp.getLength(),
					sourceComp.getFieldName(), comment);
			}
		}
	}
Bitfield insertions can cause excess growth of structure which must be trimmed.
@param struct structure to be trimmed
@param preferredSize preferred structure size
Ghidra/Features/Base/src/main/java/ghidra/app/merge/datatypes/DataTypeMergeManager.java