@Override
	public DataTypeComponent replace(int ordinal, DataType dataType, int length,
			String componentName, String comment)
			throws IllegalArgumentException, IndexOutOfBoundsException {
		lock.acquire();
		try {
			checkDeleted();

			if (ordinal < 0 || ordinal >= numComponents) {
				throw new IndexOutOfBoundsException(ordinal);
			}

			dataType = validateDataType(dataType);

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

			length = getPreferredComponentLength(dataType, length);

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

			int index = ordinal;
			if (!isPackingEnabled()) {
				index = Collections.binarySearch(components, Integer.valueOf(ordinal),
					OrdinalComparator.INSTANCE);
			}
			if (index >= 0) {
				// defined component
				DataTypeComponentDB origDtc = components.get(index);
				offset = origDtc.getOffset();

				if (isPackingEnabled() || length == 0) {
					// case 1: packed structure or zero-length replacement - do 1-for-1 replacement
					replacedComponents.add(origDtc);
				}
				else if (origDtc.getLength() == 0) {
					// case 2: replaced component is zero-length (like-for-like replacement handled
					// by case 1 above
					throw new IllegalArgumentException("Zero-length component may only be " +
						"replaced with another zero-length component");
				}
				else if (origDtc.isBitFieldComponent()) {
					// case 3: replacing bit-field (must replace all bit-fields which overlap)
					int minOffset = origDtc.getOffset();
					int maxOffset = origDtc.getEndOffset();

					replacedComponents.add(origDtc);

					// consume bit-field overlaps before
					for (int i = index - 1; i >= 0; i--) {
						origDtc = components.get(i);
						if (origDtc.getLength() == 0 || !origDtc.containsOffset(minOffset)) {
							break;
						}
						replacedComponents.add(0, origDtc);
					}

					// consume bit-field overlaps after
					for (int i = index + 1; i < components.size(); i++) {
						origDtc = components.get(i);
						if (origDtc.getLength() == 0 || !origDtc.containsOffset(maxOffset)) {
							break;
						}
						replacedComponents.add(origDtc);
					}
				}
				else {
					// case 4: sized component replacement - do 1-for-1 replacement
					replacedComponents.add(origDtc);
				}
			}
			else {
				// case 5: undefined component replaced (non-packed only)
				index = -index - 1;
				offset = ordinal;
				if (index > 0) {
					// use previous defined component to compute undefined offset
					DataTypeComponent dtc = components.get(index - 1);
					offset = dtc.getEndOffset() + ordinal - dtc.getOrdinal();
					if (dtc.getLength() == 0) {
						--offset;
					}
				}
				DataTypeComponentDB origDtc =
					new DataTypeComponentDB(dataMgr, this, ordinal, offset);
				if (dataType == DataType.DEFAULT) {
					return origDtc; // no change
				}
				replacedComponents.add(origDtc);
			}

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

			return replaceComponent != null ? replaceComponent : getComponent(ordinal);
		}
		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