@Override
	protected boolean replaceRange(int startRowIndex, int endRowIndex, DataType datatype,
			int length, TaskMonitor monitor)
			throws InvalidDataTypeException, InsufficientBytesException, CancelledException {

		if (startRowIndex > endRowIndex) {
			return false;
		}

		// Get the size of the range.
		DataTypeComponent startComp = getComponent(startRowIndex);
		DataTypeComponent endComp = getComponent(endRowIndex);
		int numBytesInRange = endComp.getOffset() + endComp.getLength();
		numBytesInRange -= startComp.getOffset();

		if (length > numBytesInRange) {
			throw new InsufficientBytesException(
				"\"" + datatype.getDisplayName() + "\" does not fit in selection.");
		}

		// Determine how many copies of new data type to add.
		int numComps = numBytesInRange / length;

		// Get the field name and comment before removing.
		String fieldName = startComp.getFieldName();
		String comment = startComp.getComment();

		FieldSelection overlap = new FieldSelection();
		overlap.addRange(startRowIndex, endRowIndex + 1);
		overlap.intersect(selection);
		boolean replacedSelected = (overlap.getNumRanges() > 0);

		int txId = viewDTM.startTransaction("Replace Multiple");
		try {
			// Remove the selected components.
			deleteComponentRange(startRowIndex, endRowIndex, monitor);

			int beginUndefs = startRowIndex + numComps;
			// Create the new components.
			insertMultiple(startRowIndex, datatype, length, numComps, monitor);
			int indexAfterMultiple = startRowIndex + numComps;
			if (replacedSelected) {
				selection.addRange(startRowIndex, indexAfterMultiple);
				fixSelection();
			}

			DataTypeComponent comp = getComponent(startRowIndex);
			// Set the field name and comment the same as before
			try {
				comp.setFieldName(fieldName);
			}
			catch (DuplicateNameException exc) {
				Msg.showError(this, null, null, null);
			}
			comp.setComment(comment);

			// Create any needed undefined data types.
			int remainingLength = numBytesInRange - (numComps * length);
			if (remainingLength > 0 && isShowingUndefinedBytes()) {
				try {
					insertComponentMultiple(beginUndefs, DataType.DEFAULT,
						DataType.DEFAULT.getLength(), remainingLength, monitor);
					if (replacedSelected) {
						selection.addRange(indexAfterMultiple,
							indexAfterMultiple + remainingLength);
					}
				}
				catch (InvalidDataTypeException idte) {
					Msg.showError(this, null, "Structure Editor Error", idte.getMessage());
				}
			}
			else if (remainingLength < 0) {
				return false;
			}
			return true;
		}
		finally {
			viewDTM.endTransaction(txId, true);
		}
	}
Returns the number of bytes that are included in the current selection
range.

@param range the range of indices for the component's whose sizes should
be added together.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java