function prepareEditDialog(trayBody, nodeEditPanes, node, definition, prefix, defaultTab, done) {
        var finishedBuilding = false;
        var completePrepare = function() {

            var editorTabEl = $('<ul></ul>').appendTo(trayBody);
            var editorContent = $('<div></div>').appendTo(trayBody);

            var editorTabs = RED.tabs.create({
                element:editorTabEl,
                onchange:function(tab) {
                    editorContent.children().hide();
                    tab.content.show();
                    if (tab.onchange) {
                        tab.onchange.call(tab);
                    }
                    if (finishedBuilding) {
                        RED.tray.resize();
                    }
                },
                collapsible: true,
                menu: false
            });

            var activeEditPanes = [];

            nodeEditPanes = nodeEditPanes.slice();
            for (var i in filteredEditPanes) {
                if (filteredEditPanes.hasOwnProperty(i)) {
                    if (filteredEditPanes[i](node)) {
                        nodeEditPanes.push(i);
                    }
                }
            }

            nodeEditPanes.forEach(function(id) {
                try {
                    var editPaneDefinition = editPanes[id];
                    if (editPaneDefinition) {
                        if (typeof editPaneDefinition === 'function') {
                            editPaneDefinition = editPaneDefinition.call(editPaneDefinition, node);
                        }
                        var editPaneContent = $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide();
                        editPaneDefinition.create.call(editPaneDefinition,editPaneContent);
                        var editTab = {
                            id: id,
                            label: editPaneDefinition.label,
                            name: editPaneDefinition.name,
                            iconClass: editPaneDefinition.iconClass,
                            content: editPaneContent,
                            onchange: function() {
                                if (editPaneDefinition.show) {
                                    editPaneDefinition.show.call(editPaneDefinition)
                                }
                            }
                        }
                        editorTabs.addTab(editTab);
                        activeEditPanes.push(editPaneDefinition);
                    } else {
                        console.warn("Unregisted edit pane:",id)
                    }
                } catch(err) {
                    console.log(id,err);
                }
            });

            for (var d in definition.defaults) {
                if (definition.defaults.hasOwnProperty(d)) {
                    if (definition.defaults[d].type) {
                        if (!definition.defaults[d]._type.array) {
                            var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
                            if (configTypeDef && configTypeDef.category === 'config') {
                                if (configTypeDef.exclusive) {
                                    prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
                                } else {
                                    prepareConfigNodeSelect(node,d,definition.defaults[d].type,prefix,definition.defaults[d].filter);
                                }
                            } else {
                                console.log("Unknown type:", definition.defaults[d].type);
                                preparePropertyEditor(node,d,prefix,definition.defaults);
                            }
                        }
                    } else {
                        preparePropertyEditor(node,d,prefix,definition.defaults);
                    }
                    attachPropertyChangeHandler(node,definition.defaults,d,prefix);
                }
            }

            if (!/^subflow:/.test(definition.type)) {
                populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
            }

            if (definition.oneditprepare) {
                try {
                    definition.oneditprepare.call(node);
                } catch(err) {
                    console.log("oneditprepare",node.id,node.type,err.toString());
                    console.log(err.stack);
                }
            }

            // Now invoke any change handlers added to the fields - passing true
            // to prevent full node validation from being triggered each time
            for (var d in definition.defaults) {
                if (definition.defaults.hasOwnProperty(d)) {
                    var el = $("#"+prefix+"-"+d);
                    el.attr("skipValidation", true);
                    if (el.data("noderedTypedInput") !== undefined) {
                        el.trigger("change",[el.typedInput('type'),el.typedInput('value')]);
                    } else {
                        el.trigger("change");
                    }
                    el.removeAttr("skipValidation");
                }
            }
            if (definition.credentials) {
                for (d in definition.credentials) {
                    if (definition.credentials.hasOwnProperty(d)) {
                        var el = $("#"+prefix+"-"+d);
                        el.attr("skipValidation", true);
                        if (el.data("noderedTypedInput") !== undefined) {
                            el.trigger("change",[el.typedInput('type'),el.typedInput('value')]);
                        } else {
                            el.trigger("change");
                        }
                        el.removeAttr("skipValidation");
                    }
                }
            }
            validateNodeEditor(node,prefix);
            finishedBuilding = true;
            if (defaultTab) {
                editorTabs.activateTab(defaultTab);
            }
            if (done) {
                done(activeEditPanes);
            }
        }
        if (definition.credentials || /^subflow:/.test(definition.type) || node.type === "group" || node.type === "tab") {
            if (node.credentials) {
                populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
                completePrepare();
            } else {
                var nodeType = node.type;
                if  (/^subflow:/.test(nodeType)) {
                    nodeType = "subflow"
                }
                getNodeCredentials(nodeType, node.id, function(data) {
                    if (data) {
                        node.credentials = data;
                        node.credentials._ = $.extend(true,{},data);
                    }
                    completePrepare();
                });
            }
        } else {
            completePrepare();
        }
    }
Prepare all of the editor dialog fields
@param trayBody - the tray body to populate
@param nodeEditPanes - array of edit pane ids to add to the dialog
@param node - the node being edited
@param definition - the node definition
@param prefix - the prefix to use in the input element ids (node-input|node-config-input)
@param default - the id of the tab to show by default