//Draws and updates the select blueprint button
    private void ProcessSelectBlueprintButton()
    {
        //If the developer presses the select blueprint button
        if (GUILayout.Button("Select Blueprint"))
        {
            //Get blueprint filepath from the developer
            string inspectorBlueprintFilepath = EditorUtility.OpenFilePanel("Select Blueprint", Application.dataPath + "/Resources/Blueprints", "txt");

            //If the inspector blueprint filepath is valid
            if (inspectorBlueprintFilepath != "" && File.Exists(inspectorBlueprintFilepath))
            {
                //Create the inspector blueprint
                inspectorBlueprint = new Blueprint(inspectorBlueprintFilepath);
                inspectorBlueprint.Load();

                //Update the blueprint filepath string
                blueprintManager.blueprintFilepath = inspectorBlueprintFilepath;

                //Update the blueprint JSON string
                blueprintManager.blueprintJSON = inspectorBlueprint.ConvertToJSON();

                //Enable saving changes
                EnableSavingChanges();
            }
        }
    }
    //Draws and updates the blueprint manager inspector
    private void ProcessBlueprintManagerInspector()
    {
        //Render the blueprints title
        EditorGUILayout.Separator();
        GUILayout.Label(BlueprintPathHelper.GetNameFromPath(blueprintManager.blueprintFilepath), BlueprintStyleHelper.GetBlueprintHeaderTextStyle());
        EditorGUILayout.Separator();

        //If the inspector blueprint is not valid
        if (inspectorBlueprint == null)
        {
            //Create the inspector blueprint
            inspectorBlueprint = new Blueprint();
            inspectorBlueprint.Load(blueprintManager.blueprintJSON);

            //Create temporary blueprint
            Blueprint tempBlueprint = new Blueprint(blueprintManager.blueprintFilepath);
            tempBlueprint.Load();

            //If the blueprints are different
            if (!BlueprintComparisonHelper.BlueprintsMatch(inspectorBlueprint, tempBlueprint))
            {
                //Restore applicable variables
                BlueprintVariableHelper.RestoreVariables(inspectorBlueprint, ref tempBlueprint);

                //Update the blueprint JSON strings
                blueprintManager.blueprintJSON = tempBlueprint.ConvertToJSON();

                //Reload the inspector blueprint
                inspectorBlueprint.Load(blueprintManager.blueprintJSON);

                //Enable saving changes
                EnableSavingChanges();
            }
        }

        //For each blueprint node in the inspector blueprint
        for (int blueprintNodeIndex = 0; blueprintNodeIndex < inspectorBlueprint.GetBlueprintNodeCount(); blueprintNodeIndex++)
        {
            //If the blueprint node is a variable
            if (inspectorBlueprint.GetBlueprintNodeAt(blueprintNodeIndex) as BlueprintNodeVariable != null)
            {
                //Render the variable inspector
                if ((inspectorBlueprint.GetBlueprintNodeAt(blueprintNodeIndex) as BlueprintNodeVariable).RenderInspector())
                {
                    //Update the blueprint JSON strings
                    blueprintManager.blueprintJSON = inspectorBlueprint.ConvertToJSON();

                    //Enable saving changes
                    EnableSavingChanges();
                }
            }
        }
    }
    //Initialize the blueprint node blueprint
    public override void Initialize()
    {
        //Initialize the blueprint node blueprint input and output execution connections
        inputExecutionConnection = new BlueprintConnectionInputExecution();
        inputExecutionConnection.Initialize(blueprintID, nodeID, 0, true);
        outputExecutionConnection = new BlueprintConnectionOutputExecution();
        outputExecutionConnection.Initialize(blueprintID, nodeID, 0, false);

        //If the blueprint JSON is valid
        if (blueprintJSON != "")
        {
            //Initialize the blueprint node blueprint from the blueprint filepath
            editorBlueprint = new Blueprint(blueprintFilepath);
            editorBlueprint.Load();
        }
        //Otherwise
        else
        {
            //Initialize the blueprint node blueprint from the blueprint filepath
            editorBlueprint = new Blueprint(blueprintFilepath);
            editorBlueprint.Load();
        }

        //For each node in the blueprint
        for (int nodeIndex = 0; nodeIndex < editorBlueprint.GetBlueprintNodeCount(); nodeIndex++)
        {
            //If the blueprint node is a variable
            if (editorBlueprint.GetBlueprintNodeAt(nodeIndex) as BlueprintNodeVariable != null)
            {
                //Add input connection
                connections.Add(((BlueprintNodeVariable)editorBlueprint.GetBlueprintNodeAt(nodeIndex)).GenerateInputConnection());
                connections[connections.Count - 1].Initialize(blueprintID, nodeID, connections.Count, true);
            }
        }

        //Update the blueprint JSON string
        blueprintJSON = editorBlueprint.ConvertToJSON();
    }
    //Renders the blueprint node blueprint body components
    protected override void RenderBodyComponents()
    {
        //If the editor blueprint node is not valid
        if (editorBlueprint == null)
        {
            //Initialize temporary blueprint
            Blueprint tempBlueprint = new Blueprint();
            tempBlueprint.Load(blueprintJSON);

            //Initialize the editor blueprint
            editorBlueprint = new Blueprint(blueprintFilepath);
            editorBlueprint.Load();

            //Attribute storing the number of variables detected
            int variablesDetected = 0;

            //For each blueprint node in the editor blueprint
            for (int nodeIndex = 0; nodeIndex < editorBlueprint.GetBlueprintNodeCount(); nodeIndex++)
            {
                //If the blueprint node is a variable
                if (editorBlueprint.GetBlueprintNodeAt(nodeIndex) as BlueprintNodeVariable != null)
                {
                    //If enough connections already exist
                    if (connections.Count > variablesDetected)
                    {
                        //If the connection types are not compatible
                        if (connections[variablesDetected].GetType() != ((BlueprintNodeVariable)editorBlueprint.GetBlueprintNodeAt(nodeIndex)).GenerateInputConnection().GetType())
                        {
                            //Destroy the connection
                            connections[variablesDetected].DestroyConnection();

                            //Replace the connection with a compatible connection
                            connections[variablesDetected] = ((BlueprintNodeVariable)editorBlueprint.GetBlueprintNodeAt(nodeIndex)).GenerateInputConnection();
                            connections[variablesDetected].Initialize(blueprintID, nodeID, variablesDetected + 1, true);
                        }
                    }
                    //Otherwise
                    else
                    {
                        //Add a connection
                        connections.Add(((BlueprintNodeVariable)editorBlueprint.GetBlueprintNodeAt(nodeIndex)).GenerateInputConnection());
                        connections[connections.Count - 1].Initialize(blueprintID, nodeID, connections.Count, true);
                    }

                    //Increment the variables detected attribute
                    variablesDetected += 1;
                }
            }

            //While there are more connections then needed
            while (connections.Count > variablesDetected)
            {
                //Destroy the last connection
                connections[connections.Count - 1].DestroyConnection();

                //Remove the last connection
                connections.RemoveAt(connections.Count - 1);
            }

            //Restore variables from the temp blueprint in the editor blueprint
            BlueprintVariableHelper.RestoreVariables(tempBlueprint, ref editorBlueprint);

            //Update the blueprint JSON string
            blueprintJSON = editorBlueprint.ConvertToJSON();
        }

        //Attribute for keeping track of the section in the blueprint node to render the variable type name information
        int variableSection = 1;

        //For each node in the editor blueprint
        for (int nodeIndex = 0; nodeIndex < editorBlueprint.GetBlueprintNodeCount(); nodeIndex++)
        {
            //If the editor blueprint node is a variable
            if (editorBlueprint.GetBlueprintNodeAt(nodeIndex) as BlueprintNodeVariable != null)
            {
                //Render the blueprint node variables type name information
                BeginSection(variableSection);
                ((BlueprintNodeVariable)editorBlueprint.GetBlueprintNodeAt(nodeIndex)).RenderTypeNameInformation();
                EndSection();

                //Increment the variable section
                variableSection += 1;
            }
        }
    }