private static void ConfigureSystemCommands(HyperNodeService service, IHyperNodeConfiguration config)
        {
            // Grab our user-defined default for system commands being enabled or disabled
            bool?userDefinedSystemCommandsEnabledDefault = null;
            var  systemCommandsCollection = config.SystemCommands;

            if (systemCommandsCollection != null)
            {
                userDefinedSystemCommandsEnabledDefault = systemCommandsCollection.Enabled;
            }

            // If the user didn't configure the system commands, they will be on by default (so that we can get task statuses and such)
            var actualDefaultEnabled = userDefinedSystemCommandsEnabledDefault ?? true;

            // Make all commands enabled or disabled according to the user-defined default, or the HyperNode's default if the user did not define a default
            var systemCommandConfigs = new List <CommandModuleConfiguration>
            {
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.GetCachedTaskProgressInfo,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(GetCachedTaskProgressInfoCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.GetNodeStatus,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(GetNodeStatusCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.GetChildNodes,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(GetChildNodesCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.Echo,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(EchoCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.EnableCommand,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(EnableCommandModuleCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.EnableActivityMonitor,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(EnableActivityMonitorCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.RenameActivityMonitor,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(RenameActivityMonitorCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.EnableTaskProgressCache,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(EnableTaskProgressCacheCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.EnableDiagnostics,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(EnableDiagnosticsCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.CancelTask,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(CancelTaskCommand)
                },
                new CommandModuleConfiguration
                {
                    CommandName       = SystemCommandName.SetTaskProgressCacheDuration,
                    Enabled           = actualDefaultEnabled,
                    CommandModuleType = typeof(SetTaskProgressCacheDurationCommand)
                }
            };

            foreach (var systemCommandConfig in systemCommandConfigs)
            {
                // Allow each system command to be enabled or disabled individually. This takes precedence over any defaults defined previously
                if (config.SystemCommands != null && config.SystemCommands.ContainsCommandName(systemCommandConfig.CommandName))
                {
                    var userConfig = config.SystemCommands.GetByCommandName(systemCommandConfig.CommandName);
                    if (userConfig != null)
                    {
                        systemCommandConfig.Enabled = userConfig.Enabled;
                    }
                }

                // Finally, try to add this system command to our collection
                service.AddCommandModuleConfiguration(systemCommandConfig);
            }
        }
        private static void ConfigureCommandModules(HyperNodeService service, IHyperNodeConfiguration config)
        {
            // Consider a null collection equivalent to an empty one
            if (config.CommandModules == null)
            {
                return;
            }

            Type collectionRequestSerializerType  = null;
            Type collectionResponseSerializerType = null;

            // First, see if we have any serializer types defined at the collection level
            if (!string.IsNullOrWhiteSpace(config.CommandModules.RequestSerializerType))
            {
                collectionRequestSerializerType = Type.GetType(config.CommandModules.RequestSerializerType, true);
            }
            if (!string.IsNullOrWhiteSpace(config.CommandModules.ResponseSerializerType))
            {
                collectionResponseSerializerType = Type.GetType(config.CommandModules.ResponseSerializerType, true);
            }

            foreach (var commandModuleConfig in config.CommandModules)
            {
                var commandModuleType = Type.GetType(commandModuleConfig.CommandModuleType, true);
                if (commandModuleType.GetInterfaces().Contains(typeof(ICommandModule)))
                {
                    Type commandRequestSerializerType  = null;
                    Type commandResponseSerializerType = null;

                    // Now check to see if we have any serializer types defined at the command level
                    if (!string.IsNullOrWhiteSpace(commandModuleConfig.RequestSerializerType))
                    {
                        commandRequestSerializerType = Type.GetType(commandModuleConfig.RequestSerializerType, true);
                    }
                    if (!string.IsNullOrWhiteSpace(commandModuleConfig.ResponseSerializerType))
                    {
                        commandResponseSerializerType = Type.GetType(commandModuleConfig.ResponseSerializerType, true);
                    }

                    // Our final configuration allows command-level serializer types to take precedence, if available. Otherwise, the collection-level types are used.
                    var configRequestSerializerType  = commandRequestSerializerType ?? collectionRequestSerializerType;
                    var configResponseSerializerType = commandResponseSerializerType ?? collectionResponseSerializerType;

                    ICommandRequestSerializer  configRequestSerializer  = null;
                    ICommandResponseSerializer configResponseSerializer = null;

                    // Attempt construction of config-level serializer types
                    if (configRequestSerializerType != null)
                    {
                        configRequestSerializer = (ICommandRequestSerializer)Activator.CreateInstance(configRequestSerializerType);
                    }
                    if (configResponseSerializerType != null)
                    {
                        configResponseSerializer = (ICommandResponseSerializer)Activator.CreateInstance(configResponseSerializerType);
                    }

                    // Finally, construct our command module configuration
                    var commandConfig = new CommandModuleConfiguration
                    {
                        CommandName        = commandModuleConfig.CommandName,
                        Enabled            = commandModuleConfig.Enabled,
                        CommandModuleType  = commandModuleType,
                        RequestSerializer  = configRequestSerializer ?? DefaultRequestSerializer,
                        ResponseSerializer = configResponseSerializer ?? DefaultResponseSerializer
                    };

                    service.AddCommandModuleConfiguration(commandConfig);
                }
            }
        }