@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.");
		}

		lock.acquire();
		try {
			checkDeleted();

			if (offset >= structLength) {
				throw new IllegalArgumentException(
					"Offset " + offset + " is beyond end of structure (" + structLength + ").");
			}

			dataType = validateDataType(dataType);
			dataType = resolve(dataType);
			checkAncestry(dataType);

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

			DataTypeComponentDB 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 DataTypeComponentDB(dataMgr, this, 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 structure 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 DataTypeComponentDB(dataMgr, this, 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);
		}
		catch (DataTypeDependencyException e) {
			throw new IllegalArgumentException(e.getMessage(), e);
		}
		catch (IOException e) {
			dataMgr.dbError(e);
			return null;
		}
		finally {
			lock.release();
		}
	}
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)
@throws IllegalArgumentException if unable to identify/make sufficient space
@throws IOException if an IO error occurs
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java