private static SymbolDatabaseAdapter copyToTempAndFixupRecords(AddressMap addrMap,
			SymbolDatabaseAdapter oldAdapter, DBHandle tmpHandle, TaskMonitor monitor)
			throws IOException, CancelledException, VersionException {

		AddressMap oldAddrMap = addrMap.getOldAddressMap();

		long nextKey = 1; // only used for V0 upgrade if a record with key 0 is encountered	
		if (oldAdapter instanceof SymbolDatabaseAdapterV0) {
			// V0 is so old that there is not enough info in the current record to create new
			// records. So store the current info in a temp database table and complete the upgrade
			// when SymbolManager.programReady() is called. The missing info can be retrieved from
			// other managers in the program at that point.
			nextKey =
				((SymbolDatabaseAdapterV0) oldAdapter).extractLocalSymbols(tmpHandle, monitor);
		}

		SymbolDatabaseAdapterV4 tmpAdapter = new SymbolDatabaseAdapterV4(tmpHandle, addrMap, true);
		RecordIterator iter = oldAdapter.getSymbols();
		while (iter.hasNext()) {
			monitor.checkCancelled();
			DBRecord rec = iter.next();
			Address addr = oldAddrMap.decodeAddress(rec.getLongValue(SYMBOL_ADDR_COL));
			rec.setLongValue(SYMBOL_ADDR_COL, addrMap.getKey(addr, true));

			// We don't allow 0 keys starting with V1, set its key to next available
			// which we got from the call to extractLocalSymbols() above
			if (rec.getKey() == 0) {
				rec.setKey(Math.max(1, nextKey));
			}

			tmpAdapter.updateSymbolRecord(rec);
			monitor.incrementProgress(1);
		}

		return tmpAdapter;
	}
Gets a new SymbolDatabaseAdapter
@param dbHandle the database handle
@param openMode the open mode
@param addrMap the address map
@param monitor the progress monitor
@return a new SymbolDatabaseAdapter
@throws VersionException if the database table does not match the adapter
@throws CancelledException if the user cancels an upgrade
@throws IOException if a database io error occurs
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDatabaseAdapter.java