private DataTypeComponent doAdd(DataType dataType, int length, String name, String comment,
			boolean validatePackAndNotify)
			throws DataTypeDependencyException, IllegalArgumentException {

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

			if (validatePackAndNotify) {
				dataType = validateDataType(dataType);
				dataType = resolve(dataType);
				checkAncestry(dataType);
			}

			DataTypeComponentDB dtc = null;
			try {
				if (dataType == DataType.DEFAULT) {
					// assume non-packed structure - structure will grow by 1-byte below
					dtc = new DataTypeComponentDB(dataMgr, this, numComponents, structLength);
				}
				else {
					int componentLength = getPreferredComponentLength(dataType, length);
					DBRecord rec = componentAdapter.createRecord(dataMgr.getResolvedID(dataType),
						key, componentLength, numComponents, structLength, name, comment);
					dtc = new DataTypeComponentDB(dataMgr, componentAdapter, this, rec);
					dataType.addParent(this);
					components.add(dtc);
				}

				int structureGrowth = dtc.getLength();
				if (structureGrowth != 0 && !isPackingEnabled() && length > 0) {
					structureGrowth = length;
				}

				++numComponents;
				structLength += structureGrowth;

				if (validatePackAndNotify) { // else caller responsible for record updates
					if (isPackingEnabled()) {
						repack(false, false); // may not recognize length change
					}
					record.setIntValue(CompositeDBAdapter.COMPOSITE_NUM_COMPONENTS_COL,
						numComponents);
					record.setIntValue(CompositeDBAdapter.COMPOSITE_LENGTH_COL, structLength);
					compositeAdapter.updateRecord(record, true); // update timestamp
					notifySizeChanged(false);
				}
			}
			catch (IOException e) {
				dataMgr.dbError(e);
			}
			return dtc;
		}
		finally {
			lock.release();
		}
	}
Eliminate use of old trailing flex-array specification which is now specified using a
zero-element array.  Due to the specification of a new array datatype this must handle two
cases when an old flex-array component is exists:
<ol>
<li>read-only case: associated {@link DataTypeManagerDB} is not updatable.  This is the
normal case for an open archive.  A non-DB ArrayDataType must be employed with an immutable
{@link DataTypeProxyComponentDB} in place of the flex-array component.</li>
<li>upgrade (open for update with open transaction): the flex-array record is modified to
indicate an appropriate resolved zero-element array.
</ol>
<p>
NOTE: When {@link DataTypeManagerDB} is instantiated for update an upgrade must be forced
based upon the {@link CompositeDBAdapter#isFlexArrayMigrationRequired()} indicator.  The
upgrade logic(see
{@link DataTypeManagerDB#migrateOldFlexArrayComponentsIfRequired(TaskMonitor)}) instantiates
all structures within the databases with an open transaction allowing this method to perform
the necessary flex-array record migration.
<p>
NOTE: The offset of the migrated flex array component and structure length may change during
upgrade when packing is enabled when the original packed structure length did not properly
factor the flex-array alignment.  Repack does not occur in the read-only case.

@param oldFlexArrayRecord record which corresponds to an old flex-array component
@throws IOException if a database error occurs
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java