void addToVersionControl(String comment, boolean keepCheckedOut, TaskMonitor monitor)
			throws IOException, CancelledException {

		checkCanAddToRepository();

		if (busy.getAndSet(true)) {
			throw new FileInUseException(name + " is busy");
		}

		DomainObjectAdapterDB inUseDomainObj = null;
		mergeInProgress = true;
		projectData.mergeStarted();
		try {
			inUseDomainObj = getAndLockInUseDomainObjectForMergeUpdate("checkin");

			if (isLinkFile()) {
				keepCheckedOut = false;
			}
			else if (inUseDomainObj != null && !keepCheckedOut) {
				keepCheckedOut = true;
				Msg.warn(this, "File currently open - must keep checked-out: " + name);
			}

			synchronized (fileSystem) {

				String parentPath = parent.getPathname();
				String user = ClientUtil.getUserName();
				try {
					if (folderItem instanceof DatabaseItem) {
						DatabaseItem databaseItem = (DatabaseItem) folderItem;
						BufferFile bufferFile = databaseItem.open();
						try {
							versionedFolderItem = versionedFileSystem.createDatabase(parentPath,
								name, folderItem.getFileID(), bufferFile, comment,
								folderItem.getContentType(), false, monitor, user);
						}
						finally {
							bufferFile.dispose();
						}
					}
					else if (folderItem instanceof DataFileItem) {
						DataFileItem dataFileItem = (DataFileItem) folderItem;
						InputStream istream = dataFileItem.getInputStream();
						try {
							versionedFolderItem = versionedFileSystem.createDataFile(parentPath,
								name, istream, comment, folderItem.getContentType(), monitor);
						}
						finally {
							istream.close();
						}
					}
					else {
						throw new IOException(
							"Unable to add unsupported content to version control");
					}
				}
				catch (InvalidNameException e) {
					throw new AssertException("Unexpected error", e);
				}

				if (keepCheckedOut) {

					// Maintain exclusive checkout if private repository or file is open for update
					boolean exclusive = !versionedFileSystem.isShared() || (inUseDomainObj != null);

					ProjectLocator projectLocator = parent.getProjectLocator();
					CheckoutType checkoutType;
					if (projectLocator.isTransient()) {
						checkoutType = CheckoutType.TRANSIENT;
						exclusive = true;
					}
					else {
						// All checkouts for non-shared versioning are treated as exclusive
						checkoutType =
							(exclusive || !versionedFileSystem.isShared()) ? CheckoutType.EXCLUSIVE
									: CheckoutType.NORMAL;
					}
					ItemCheckoutStatus checkout = versionedFolderItem.checkout(checkoutType, user,
						ItemCheckoutStatus.getProjectPath(projectLocator.toString(),
							projectLocator.isTransient()));
					folderItem.setCheckout(checkout.getCheckoutId(), exclusive,
						checkout.getCheckoutVersion(), folderItem.getCurrentVersion());

					if (inUseDomainObj != null) {
						// Reset source file and change-sets for open database
						getContentHandler().resetDBSourceFile(folderItem, inUseDomainObj);
					}
				}
				else {
					// NOTE: file open read-only may prevent removal and result in hijack
					try {
						folderItem.delete(-1, ClientUtil.getUserName());
						folderItem = null;
					}
					catch (FileInUseException e1) {
						// Ignore - should result in Hijacked file
					}
				}

			} // end of synchronized block

			if (inUseDomainObj != null) {
				inUseDomainObj.domainObjectRestored();
			}
		}
		finally {
			unlockDomainObject(inUseDomainObj);
			busy.set(false);
			mergeInProgress = false;
			projectData.mergeEnded();
			parent.deleteLocalFolderIfEmpty();
			parent.fileChanged(name);
		}
	}
Adds this private file to version control.
@param comment new version comment
@param keepCheckedOut if true, the file will be initially checked-out
@param monitor progress monitor
@throws FileInUseException if this file is in-use.
@throws IOException if an IO or access error occurs.  Also if file is not 
private.
@throws CancelledException if the monitor cancelled the operation
Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java