private string _sbExceptionsLock    = "sbExceptionsLock"; // Lock object



        public void PI_Init(int nToolID, EngineInterface engineInterface, XmlElement pXmlProperties)
        {
            DebugMessage($"PI_Init() Entering; ToolID={_toolID}");

            _toolID          = nToolID;
            _engineInterface = engineInterface;
            _xmlProperties   = pXmlProperties;

            // Use the information in the pXmlProperties parameter to get the user control info

            XmlElement configElement = XmlHelpers.GetFirstChildByName(_xmlProperties, "Configuration", true);

            if (configElement != null)
            {
                getConfigSetting(configElement, Constants.EXEPATHFIELDKEY, ref _exePathField);

                getConfigSetting(configElement, Constants.STDOUTFIELDKEY, ref _stdOutField);
                getConfigSetting(configElement, Constants.RETCODEFIELDKEY, ref _retCodeField);
                getConfigSetting(configElement, Constants.EXCEPTIONFIELDKEY, ref _exceptionsField);
                getConfigSetting(configElement, Constants.DIAGNOSTICFIELDKEY, ref _diagnosticField);

                getConfigSetting(configElement, Constants.AUTOESCAPEKEY, ref _autoEscape);

                getConfigSetting(configElement, Constants.SELECTEDCOLSKEY, ref _selectedCols);
            }

            _outputHelper = new AlteryxRecordInfoNet.PluginOutputConnectionHelper(_toolID, _engineInterface);

            DebugMessage($"PI_Init() Exiting; ToolID={_toolID}");
        }
        ///////////////////////////////////////////////////////////////////////
        // HELPERS
        //

        private void getConfigSetting(XmlElement configElement, string key, ref string memberToSet)
        {
            XmlElement xe = XmlHelpers.GetFirstChildByName(configElement, key, false);

            if (xe != null)
            {
                if (!string.IsNullOrWhiteSpace(xe.InnerText))
                {
                    memberToSet = xe.InnerText;
                }
            }
        }