function addSubflow(sf, createNewIds) {
        if (createNewIds) {
            // Update the Subflow name to highlight that this is a copy
            const subflowNames = Object.keys(subflows).map(function (sfid) {
                return subflows[sfid].name || "";
            })
            subflowNames.sort()

            let copyNumber = 1;
            let subflowName = sf.name;
            subflowNames.forEach(function(name) {
                if (subflowName == name) {
                    subflowName = sf.name + " (" + copyNumber + ")";
                    copyNumber++;
                }
            });

            sf.name = subflowName;
        }

        sf.instances = [];

        subflows[sf.id] = sf;
        allNodes.addTab(sf.id);
        linkTabMap[sf.id] = [];

        RED.nodes.registerType("subflow:"+sf.id, {
            defaults:{
                name:{value:""},
                env:{value:[], validate: function(value) {
                    const errors = []
                    if (value) {
                        value.forEach(env => {
                            const r = RED.utils.validateTypedProperty(env.value, env.type)
                            if (r !== true) {
                                errors.push(env.name+': '+r)
                            }
                        })
                    }
                    if (errors.length === 0) {
                        return true
                    } else {
                        return errors
                    }
                }}
            },
            icon: function() { return sf.icon||"subflow.svg" },
            category: sf.category || "subflows",
            inputs: sf.in.length,
            outputs: sf.out.length,
            color: sf.color || "#DDAA99",
            label: function() { return this.name||RED.nodes.subflow(sf.id).name },
            labelStyle: function() { return this.name?"red-ui-flow-node-label-italic":""; },
            paletteLabel: function() { return RED.nodes.subflow(sf.id).name },
            inputLabels: function(i) { return sf.inputLabels?sf.inputLabels[i]:null },
            outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null },
            oneditprepare: function() {
                if (this.type !== 'subflow') {
                    // A subflow instance node
                    RED.subflow.buildEditForm("subflow",this);
                } else {
                    // A subflow template node
                    RED.subflow.buildEditForm("subflow-template", this);
                }
            },
            oneditresize: function(size) {
                if (this.type === 'subflow') {
                    $("#node-input-env-container").editableList('height',size.height - 80);
                }
            },
            set:{
                module: "node-red"
            }
        });

        sf._def = RED.nodes.getType("subflow:"+sf.id);
        RED.events.emit("subflows:add",sf);
    }
Add a Subflow to the Workspace

@param {object} sf The Subflow to add.
@param {boolean|undefined} createNewIds Whether to update the name.