void ConfigUserInterface(BasicTriListWithSmartObject currentDevice)
        {
            try
            {
                if (typeof(TswX60BaseClass).IsAssignableFrom(currentDevice.GetType()))
                {
                    ((TswX60BaseClass)currentDevice).ExtenderHardButtonReservedSigs.Use(); // must be done before registration. May cause, System.InvalidCastException: InvalidCastException
                    OnDebug(eDebugEventType.Info, "ui_{0:X2} {1} using HardButtonReservedSigs", currentDevice.ID, currentDevice.Name);
                }
                if (currentDevice.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
                {
                    OnDebug(eDebugEventType.Info, "ui_{0:X2} {1} registration success", currentDevice.ID, currentDevice.Name);
                }
                else
                {
                    OnDebug(eDebugEventType.Error, "ui_{0:X2} {1} failed registration. Cause: {2}", currentDevice.ID, currentDevice.Name, currentDevice.RegistrationFailureReason);
                }
                currentDevice.OnlineStatusChange += new OnlineStatusChangeEventHandler(ui_OnlineStatusChange);
                currentDevice.SigChange          += new SigEventHandler(ui_SigChange);

                LoadUserInterfaceSmartObjectGraphics(currentDevice);
            }
            catch (Exception e)
            {
                OnDebug(eDebugEventType.Error, "Exception in ConfigUserInterfaces: {0}", e.Message);
            }
        }
        bool isAccessLevelChosen = false;                               // Indicates whether user has clicked an access level (cannot create group if false)
        /////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// ControlSystem Constructor. Starting point for the SIMPL#Pro program.
        /// Use the constructor to:
        /// * Initialize the maximum number of threads (max = 400)
        /// * Register devices
        /// * Register event handlers
        /// * Add Console Commands
        ///
        /// Please be aware that the constructor needs to exit quickly; if it doesn't
        /// exit in time, the SIMPL#Pro program will exit.
        ///
        /// You cannot send / receive data in the constructor
        /// </summary>
        public ControlSystem()
            : base()
        {
            try
            {
                //Subscribe to the controller events (System, Program, and Ethernet)
                CrestronEnvironment.SystemEventHandler        += new SystemEventHandler(ControlSystem_ControllerSystemEventHandler);
                CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(ControlSystem_ControllerProgramEventHandler);

                // IPID = 3
                panel = new Tsw752(0x3, this);

                // Subscribe to all signal changes from the touchpanel. This handler will be invoked everytime the
                // user presses a button or types into a text box
                panel.SigChange += new SigEventHandler(Panel_SigChange);
                // If the smart graphics file exists, load it to the panel
                if (File.Exists(Directory.GetApplicationDirectory() + "\\" + sgdFileName))
                {
                    panel.LoadSmartObjects(Directory.GetApplicationDirectory() + "\\" + sgdFileName);

                    // Register the event handler for each Smart Object found
                    foreach (KeyValuePair <uint, SmartObject> so in panel.SmartObjects)
                    {
                        so.Value.SigChange += new SmartObjectSigChangeEventHandler(SmartObject_SigChange);
                    }
                }
                else
                {
                    ErrorLog.Error("Failed to load SGD file {0} for panel", sgdFileName);
                }

                if (panel.Register() != eDeviceRegistrationUnRegistrationResponse.Success)
                {
                    ErrorLog.Error("Error Registering panel at IPID {0}: {1}", panel.ID, panel.RegistrationFailureReason);
                }

                // Create the timer now, but don't start it until the user logs in
                authTimeout = new CTimer(authTimeoutCallback, Timeout.Infinite);
            }
            catch (Exception e)
            {
                CrestronConsole.PrintLine("Error in the constructor: {0}", e);
                ErrorLog.Error("Error in the constructor: {0}", e.Message);
            }
        }