internal void DoUpload()
        {
            // see if there is a project up and running
            try
            {
                string   projectName = Form.SelectedProjectName;
                SProject proj        = Form.Cmd.ServerInterface.GetProject(Form.Data, projectName);
                if (null == proj)
                {
                    throw new IcnException("No project selected", 10, "Upload");
                }

                string schema = proj.schema;
                if (string.IsNullOrEmpty(schema))
                {
                    schema = "Ifc2x3tc1";
                }
                SDeserializer deserialiser = Form.Cmd.ServerInterface.GetDeserialiser(Form.Data, proj.oid, schema);
                if (null == deserialiser)
                {
                    throw new IcnException($"Serializer '{schema}' not found in project '{projectName}'", 10, "Upload");
                }

                string path = Form.IfcEdt.Text;
                if (string.IsNullOrEmpty(path) || !File.Exists(path))
                {
                    path = Form.Cmd.BimServerExchange.AskForIfcUploadPath();
                }
                if (string.IsNullOrEmpty(path) || !File.Exists(path))
                {
                    throw new IcnException($"IFC file '{path ?? string.Empty}' not found", 10, "Upload");
                }
                // this checks if the file and project name are the same and asks the user to confirm if they are not
                if (!Form.Cmd.BimServerExchange.ValidateAndAcceptFilename(projectName, path))
                {
                    return;
                }

                // we may have linked files. And we likely will need additional controls (e.g. for the Project to upload to) and additional data to go with this
                string tag = Form.Cmd.BimServerExchange.GetFileTag(path);
                string result;
                Form.Cmd.BimServerExchange.ActivateButtons(false);
                int fileId = Form.Cmd.ServerInterface.CheckinFile(Form.Data, path, tag ?? string.Empty, proj.oid, deserialiser.oid, true, out result);
                if (fileId > 0)
                {
                    Form.CancelUploadBtn.Enabled = false;
                    fileId = Form.Cmd.ServerInterface.MonitorProcessingState(Form.Data, fileId, out result);
                }

                Form.Cmd.ShowResult($"Copy IFC file '{path}' to the BIMserver\nResult: '{result}'");

                List <SRevision> revisions = Form.Cmd.ServerInterface.GetAllFilesOfProject(Form.Data, proj);
                Form.Cmd.BimServerExchange.FillRevisionTree(revisions);
            }
            catch (IcnException iex)
            {
                iex.Display(@"Exception in Upload IFC file");
                Form.Cmd.ShowResult(iex.ToString());
            }
            catch (Exception ex)
            {
                Form.Cmd.ShowResult($"Select/add project failed ({ex.Message})");
                Form.Cmd.ShowResult(ex.Message);
            }
            finally
            {
                Form.Cmd.BimServerExchange.ActivateButtons(true);
            }
        }
        internal void QuickCheckinFile(string path, string comment)
        {
            if (string.IsNullOrEmpty(path) || !File.Exists(path))
            {
                throw new IcnException("No IFC file selected to export", 10, "QuickExport");
            }

            if (string.IsNullOrEmpty(comment))
            {
                comment = Path.GetFileName(path);
            }

            // get the projectId (from the project stored in Properties.Settings.Default.BimServerProject!)
            SProject project = Form.Cmd.ServerInterface.GetProject(Form.Data, Form.Data.ProjectName);

            if (null == project)
            {
                throw new IcnException($"Project '{Form.Data.ProjectName}' is not found on the BIMserver", 10, "QuickExport");
            }

            // get the deserializerId (from the setting of the project)
            string fileIfcFormat    = GetIFCFormatOfFile(path);   // this may contain the " (streaming)" suffix as it is meant to look up the deserializer
            string projectIfcFormat = project.schema;             // this is the actual IFC schema used in this project
            string fname            = Path.GetFileNameWithoutExtension(path);

            if (string.IsNullOrEmpty(fname))
            {
                fname = path;
            }
            if (!IfcFormatsMatch(fileIfcFormat, projectIfcFormat))
            {
                throw new IcnException($"Could not copy '{fname}' to the BIMserver. The IFC format '{fileIfcFormat}' differs from the project format '{projectIfcFormat}'", 10, "QuickExport");
            }

            SDeserializer deserialiser = Form.Cmd.ServerInterface.GetDeserialiser(Form.Data, project.oid, projectIfcFormat);

            if (null == deserialiser)
            {
                throw new IcnException($"Serializer '{projectIfcFormat}' is unknown in project '{Form.Data.ProjectName}'", 10, "QuickExport");
            }

            // do the actual export
            string result;
            int    topicId = Form.Cmd.ServerInterface.CheckinFile(Form.Data, path, comment, project.oid, deserialiser.oid, true, out result);

            if (topicId < 0)
            {
                // result is either cancelled or failed
                if (result.IndexOf("failed", StringComparison.InvariantCultureIgnoreCase) > 0)
                {
                    throw new IcnException($"Project '{fname}' is not copied to the BIMserver", 10, "QuickExport");
                }

                ShowResultInForm(result);
                return;
            }

            // What we really want to do here is start a new modeless form and have that report progress while we close this form
            // when the modeless form completes it can close and show this form again. This will probably mess up the commanders that
            // are running. And we also need to create keyboard shortcuts for the exporter as we will have to trigger the command (not just the form)
            // The better option is to run the exporter in a modeless dialog, then we can keep it up and running (but will need to guard many of its
            // commander methods against it being destroyed) and use it for output just as we do now

            // we can't cancel the processing by the BIMserver so disable that option
            ActivateCancelButton(false);

            // then run the actual monitoring process. This will make the form (and revit) block for potentially a very long time
            topicId = Form.Cmd.ServerInterface.MonitorProcessingState(Form.Data, topicId, out result);

            if (Form.Cancelling)
            {
                return;
            }

            if (0 != string.Compare(result, "OK", StringComparison.InvariantCultureIgnoreCase) &&
                0 != string.Compare(result, "Project is uploaded to the BIMserver", StringComparison.InvariantCultureIgnoreCase))
            {
                throw new IcnException($"Project '{fname}' is not copied to the BIMserver ({result})", 10, "QuickExport");
            }

            // normally we have the (final) result here stating that the upload was successful
            ShowResultInForm(result);
        }