@Override
	public ParameterDB insertParameter(int ordinal, Variable var, SourceType source)
			throws DuplicateNameException, InvalidInputException {

		manager.lock.acquire();
		try {
			startUpdate();
			checkDeleted();
			if (thunkedFunction != null) {
				return thunkedFunction.insertParameter(ordinal, var, source);
			}
			loadVariables();
			purgeBadVariables();

			int autoCnt = 0;
			if (autoParams != null) {
				autoCnt = autoParams.size();
				if (ordinal < autoCnt) {
					throw new InvalidInputException(
						"Parameter may not be inserted before auto-parameter");
				}
			}

			ordinal -= autoCnt;
			if (ordinal < 0 || ordinal > params.size()) {
				throw new IndexOutOfBoundsException("Ordinal value must be " + autoCnt +
					" <= ordinal < " + (params.size() + autoCnt) + ": " + (ordinal + autoCnt));
			}

			if (var.isUniqueVariable()) {
				throw new IllegalArgumentException(
					"Invalid parameter specified: UniqueVariable not allowed");
			}

			boolean hasCustomStorage = hasCustomVariableStorage();
			if (hasCustomStorage) {
				if (validateEnabled && var.hasStackStorage()) {
					int stackOffset = (int) var.getLastStorageVarnode().getOffset();
					if (!frame.isParameterOffset(stackOffset)) {
						throw new InvalidInputException(
							"Variable contains invalid stack parameter offset: " + var.getName() +
								"  offset " + stackOffset);
					}
				}
			}

			var = getResolvedVariable(var, false, !hasCustomStorage);

			String name = var.getName();
			SourceType paramSource = source;
			if (name == null || name.length() == 0 || paramSource == SourceType.DEFAULT ||
				SymbolUtilities.isDefaultParameterName(name)) {
				name = DEFAULT_PARAM_PREFIX;
				paramSource = SourceType.DEFAULT;
			}

			VariableStorage storage = var.getVariableStorage();
			if (!hasCustomStorage) {
				storage = VariableStorage.UNASSIGNED_STORAGE;
			}
			else if (storage.isAutoStorage()) {
				storage = new VariableStorage(program, storage.getVarnodes());
			}

			try {

				// Check for duplicate storage address
				ParameterDB p = null;
				if (storage != VariableStorage.UNASSIGNED_STORAGE) {
					for (ParameterDB oldParam : params) {
						if (oldParam.getVariableStorage().intersects(storage)) {
							p = oldParam;
							break;
						}
					}
					if (validateEnabled) {
						VariableUtilities.checkVariableConflict(this, (p != null ? p : var),
							storage, true);
					}
				}
				if (p != null) {
					// storage has been specified
					// move and update existing parameter
					if (ordinal >= params.size()) {
						ordinal = params.size() - 1;
					}
					Msg.info(this, "WARNING! Inserting overlapping parameter for function " + this +
						" at " + p.getVariableStorage() + " - Replacing existing parameter!");
					if (p.getOrdinal() != ordinal) {
						if (p != params.remove(p.getOrdinal())) {
							throw new AssertException("Inconsistent function parameter cache");
						}

						params.add(ordinal, p);
						updateParametersAndReturn();
						manager.functionChanged(this, PARAMETERS_CHANGED);
					}
					if (!DEFAULT_PARAM_PREFIX.equals(name)) {
						p.setName(name, paramSource);
					}
					p.setStorageAndDataType(storage, var.getDataType());
				}
				else {
					// create new parameter
					if (ordinal > params.size()) {
						ordinal = params.size();
					}
					if (ordinal != params.size()) {
						// shift params to make room for inserted param
						for (ParameterDB param : params) {
							int paramOrdinal = param.getOrdinal();
							if (paramOrdinal >= ordinal) {
								param.setOrdinal(paramOrdinal + 1);
							}
						}
					}
					SymbolManager symbolMgr = program.getSymbolTable();
					VariableSymbolDB s = symbolMgr.createVariableSymbol(name, this,
						SymbolType.PARAMETER, ordinal, storage, paramSource);
					s.setStorageAndDataType(storage, var.getDataType());
					p = new ParameterDB(this, s);

					params.add(ordinal, p);
					updateParametersAndReturn();
					symbolMap.put(p.symbol, p);
					manager.functionChanged(this, PARAMETERS_CHANGED);
				}
				if (var.getComment() != null) {
					p.symbol.setSymbolComment(var.getComment());
				}
				updateSignatureSourceAfterVariableChange(source, p.getDataType());
				return p;
			}
			finally {
				frame.setInvalid();
			}
		}
		finally {
			endUpdate();
			manager.lock.release();
		}
	}
@see ghidra.program.model.listing.Function#insertParameter(int, ghidra.program.model.listing.Variable, ghidra.program.model.symbol.SourceType)
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionDB.java