public void unpackage(int rowIndex, TaskMonitor monitor) throws UsrException {
		int componentOrdinal = convertRowToOrdinal(rowIndex);
		DataTypeComponent currentComp = viewComposite.getComponent(componentOrdinal);
		if (currentComp == null) {
			throw new UsrException("Can only unpackage an array or structure.");
		}
		DataType dt = currentComp.getDataType();
		if (dt instanceof TypeDef td) {
			dt = td.getBaseDataType();
		}
		if (!((dt instanceof Array) || (dt instanceof Structure))) {
			throw new UsrException("Can only unpackage an array or structure.");
		}
		if (isEditingField()) {
			endFieldEditing();
		}

		DataType currentDataType = dt;
		viewDTM.withTransaction("Unpack Component", () -> {
			// Get the field name and comment before removing.
			String fieldName = currentComp.getFieldName();
			String comment = currentComp.getComment();
			int numComps = 0;
			// This component is an array so unpackage it.
			if (currentDataType instanceof Array array) {
				int elementLen = array.getElementLength();
				numComps = array.getNumElements();
				// Remove the array.
				delete(componentOrdinal);
				if (array.isZeroLength()) {
					return;
				}
				if (numComps > 0) {
					// Add the array's elements
					try {
						DataType arrayBaseDt = array.getDataType();
						insertMultiple(rowIndex, arrayBaseDt, elementLen, numComps, monitor);
					}
					catch (InvalidDataTypeException ie) {
						// Do nothing.
					}
					catch (OutOfMemoryError memExc) {
						throw memExc; // rethrow the exception.
					}
				}
			}
			// This component is a structure so unpackage it.
			else if (currentDataType instanceof Structure struct) {
				numComps = struct.getNumComponents();
				if (numComps > 0) {
					// Remove the structure.
					int currentOffset = currentComp.getOffset();

					// TODO: may want to add this functionality into the API

					Stack<DataTypeComponent> zeroDtcStack = new Stack<>();
					int zeroStackOffset = -1;
					int zeroStackOrdinal = -1;
					int packedOrdinal = 0;

					deleteComponent(rowIndex);

					if (struct.isZeroLength()) {
						return;
					}

					if (rowIndex != 0 && !viewComposite.isPackingEnabled()) {
						// Must consume any preceeding zero-length components at the same offset
						// into the zeroDtcStack to prevent their movement on subsequent component
						// inserts at the same offset
						DataTypeComponent dtc =
							viewComposite.getDefinedComponentAtOrAfterOffset(currentOffset);
						if (dtc != null && dtc.getOffset() == currentOffset) {
							// zero-length is assumed if offset matches
							zeroStackOffset = 0;
							int componentCount = viewComposite.getNumComponents();
							while (dtc != null && dtc.getOffset() == currentOffset) {
								int ordinal = dtc.getOrdinal();
								zeroDtcStack.push(dtc);
								viewComposite.delete(ordinal);
								--componentCount;
								dtc = ordinal < componentCount ? viewComposite.getComponent(ordinal)
										: null;
							}
						}
					}

					// Add the structure's elements
					for (DataTypeComponent dtc : struct.getDefinedComponents()) {

						DataType compDt = dtc.getDataType();
						int compLength = dtc.getLength();
						int compOffset = dtc.getOffset();

						if (compOffset != zeroStackOffset && !zeroDtcStack.isEmpty()) {
							packedOrdinal += zeroDtcStack.size();
							applyZeroDtcStack(viewComposite, currentOffset, componentOrdinal,
								zeroDtcStack, zeroStackOffset, zeroStackOrdinal);
						}

						if (compLength == 0) {
							// Defer adding zero-length component until after non-zero-length
							// has been added
							if (zeroStackOffset != compOffset) {
								zeroStackOffset = compOffset;
								zeroStackOrdinal = packedOrdinal;
							}
							zeroDtcStack.push(dtc);
							continue;
						}

						if (!isPackingEnabled()) {
							if (dtc.isBitFieldComponent()) {
								BitFieldDataType bitfield = (BitFieldDataType) compDt;
								viewComposite.insertBitFieldAt(currentOffset + compOffset,
									compLength, bitfield.getBitOffset(), bitfield.getBaseDataType(),
									bitfield.getDeclaredBitSize(), dtc.getFieldName(),
									dtc.getComment());
							}
							else {
								viewComposite.insertAtOffset(currentOffset + compOffset, compDt,
									compLength, dtc.getFieldName(), dtc.getComment());
							}
						}
						else {
							viewComposite.insert(componentOrdinal + packedOrdinal, compDt,
								compLength, dtc.getFieldName(), dtc.getComment());
						}

						++packedOrdinal;
					}

					if (!zeroDtcStack.isEmpty()) {
						applyZeroDtcStack(viewComposite, currentOffset, componentOrdinal,
							zeroDtcStack, zeroStackOffset, zeroStackOrdinal);
					}
				}
			}
			selection.clear();
			selection.addRange(rowIndex, rowIndex + numComps);

			DataTypeComponent comp = getComponent(rowIndex);
			// Set the field name and comment the same as before if unspecified
			try {
				if (comp.getFieldName() == null) {
					comp.setFieldName(fieldName);
				}
			}
			catch (DuplicateNameException exc) {
				Msg.showError(this, null, null, null);
			}
			if (StringUtils.isBlank(comp.getComment())) {
				comp.setComment(comment);
			}
		});
		fixSelection();
		selectionChanged();
	}
Unpackage the selected component in the structure or array. This means replace the structure
with the data types for its component parts. For an array replace the array with the data type
for each array element.
If the component isn't a structure or union then returns false.
@param rowIndex the row
@param monitor the task monitor
@throws UsrException if the component can't be unpackaged.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java