@Override
	public DataTypeComponent replaceAtOffset(int offset, DataType dataType, int length,
			String componentName, String comment) throws IllegalArgumentException {
		if (offset < 0) {
			throw new IllegalArgumentException("Offset cannot be negative.");
		}
		if (offset >= structLength) {
			throw new IllegalArgumentException(
				"Offset " + offset + " is beyond end of structure (" + structLength + ").");
		}

		dataType = validateDataType(dataType);
		dataType = dataType.clone(dataMgr);
		checkAncestry(dataType);

		LinkedList<DataTypeComponentImpl> replacedComponents = new LinkedList<>();

		DataTypeComponentImpl origDtc = null;
		int index = Collections.binarySearch(components, Integer.valueOf(offset),
			OffsetComparator.INSTANCE);
		if (index >= 0) {

			// defined component found - advance to last one containing offset
			index = advanceToLastComponentContainingOffset(index, offset);
			origDtc = components.get(index);

			// case 1: only defined component(s) at offset are zero-length
			if (origDtc.getLength() == 0) {
				if (isPackingEnabled()) {
					// if packed: insert after zero-length component 
					return insert(index + 1, dataType, length, componentName, comment);
				}
				// if non-packed: replace undefined component which immediately follows the zero-length component
				replacedComponents.add(new DataTypeComponentImpl(DataType.DEFAULT, this, 1,
					origDtc.getOrdinal() + 1, offset));
			}

			// case 2: sized component at offset is bit-field (must replace all bit-fields which contain offset)
			else if (origDtc.isBitFieldComponent()) {
				replacedComponents.add(origDtc);
				for (int i = index - 1; i >= 0; i--) {
					origDtc = components.get(i);
					if (origDtc.getLength() == 0 || !origDtc.containsOffset(offset)) {
						break;
					}
					replacedComponents.add(0, origDtc);
				}
			}

			// case 3: normal replacement of sized component
			else {
				replacedComponents.add(origDtc);
			}
		}
		else {
			// defined component not found
			index = -index - 1;

			if (isPackingEnabled()) {
				// case 4: if replacing padding for packed struction perform insert at correct ordinal
				return insert(index, dataType, length, componentName, comment);
			}

			// case 5: replace undefined component at offset - compute undefined component to be replaced
			int ordinal = offset;
			if (index > 0) {
				// use previous defined component to determine ordinal for undefined component
				DataTypeComponent dtc = components.get(index - 1);
				ordinal = dtc.getOrdinal() + offset - dtc.getEndOffset();
			}
			origDtc = new DataTypeComponentImpl(DataType.DEFAULT, this, 1, ordinal, offset);
			if (dataType == DataType.DEFAULT) {
				return origDtc; // no change
			}
			replacedComponents.add(origDtc);
		}

		length = getPreferredComponentLength(dataType, length);

		DataTypeComponent replaceComponent = doComponentReplacement(replacedComponents, offset,
			dataType, length, componentName, comment);

		return replaceComponent != null ? replaceComponent : getComponentContaining(offset);
	}
Perform component replacement(s)
@param replacedComponents ordered list of components to be replaced
@param offset offset of component replacement
@param dataType datatype of component replacement
@param length length of component replacement
@param componentName name of component replacement (may be null)
@param comment comment for component replacement (may be null)
@return new/updated component (may be null if replacement is not a defined component)
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/StructureDataType.java